Am I doing &str copying into a long-lived map correctly?

I think a couple thousand would be a safe bet. Also, depending on what you want to measure, you could pull the allocation of the hashmap out of the function being benchmarked, and .reserve() the sufficient capacity upfront, causing the map not to reallocate.

1 Like

My real usage of this cache won't likely ever go beyond 100 entries so I think I'll go with that. I didn't mention more details but it's going to be an extremely hot and well-warmed-up cache. But as mentioned earlier, it's going to be 99% reads (hence the current insert benchmarks are mostly irrelevant; still, I wanted them in out of curiosity).

With the rest I agree. I managed to completely forget about HashMap::with_capacity. Oops.

(EDIT: The keys will be normalized / shell-expanded file names btw. So the key lengths can be anywhere from 10 to 255 characters.)

Switching from new to with_capacity improved performance by 42.5% of the &str-keyed HashMap and by 21.6% of the String-keyed HashMap.

It seems that you've already figured it out that the HashMap<&str, T> can only stores references to the variables of same scope, and you can't even insert to the map within the loop. Is it the map you want?

Not exactly. I want to be able to copy the &str instances so they are fully owned by the map and not shared with anyone. But I am reconsidering my approach currently because preliminary read/lookup benchmarks don't seem to show much difference.

Well, the &str, or in general &T is a reference, and the reference doesn't own its content. String is the owned version of the dynamic string content.

1 Like

Yep. My original preliminary optimization idea was along the lines of "heap vs. stack" but that obviously doesn't apply to a global static HashMap (in my case it will be DashMap but oh well).

Started screwing around with benchmarks, found no significant differences and the approach which was most performant gave me tons of headaches with ownership and lifetimes (as predicted by others here in this thread) so I just went ahead with normal String keys and marked @quinedot's answer as the accepted solution since it contains the most code and a good chunk of explanations.

I learned not to screw around with &str too much. It's just only for the occasional hard-coded strings in your code and nothing else, it seems. So I likely was misunderstanding its purpose in the first place -- my bad.

Thanks for everybody who participated.

The primary use of references (including &str) is to let a function inspect an argument's value without the overhead of making a clone. Storing a reference inside a structure is an advanced technique, and quickly leads to the problems you've run into here.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.