问题
Currently I have a solution where I keep track of objects I am interested in by getting their hashcode via Object.GetHashCode
and then storing them in a HashSet<int>
.
However, I have also been learning about bitmasks and bitwise operations and I am quite intrigued by them. Here is a great question that I found close to what I am looking to do. However, I cannot seem to make this work efficiently for hash codes.
There is also this question, but it seems to deal with 5-bit numbers, when hash codes are int
's (32-bits).
I do get the BitArray
solution (from the first referenced question) working, but it is not as fast as my current HashSet approach is. This is due to the sheer number of items in the BitArray
that need to be created to account for all known hash codes (int.MaxValue
).
Is there some a bitmask/bitwise operation I should consider in making this work with a BitArray
? Or have I totally gone off the beaten path here and should simply stick with my HashSet<int>
solution?
回答1:
This was indeed an instance of going off the beaten path, paired with a misunderstanding of references/memory management. In my case I was using a Dictionary<TKey, TValue>
object to store cached results from method calls on an instance. I couldn't use a ConditionalWeakTable
because there are at least three parts to a key:
- The instance that contains the method where the results are being cached.
- Said method.
- Arguments being passed into the method.
If I used a ConditionalWeakTable
I would have to create "yet another object" (class) that would require yet another allocation, but worse yet would not be referenced by anything (besides the ConditionalWeakTable
) and would get garbage collected on the first pass (this is indeed related to another open -- but now also solved -- question of mine).
After much thought around this, I have realized that the answer does indeed lie in ConditionalWeakTable
. Rather than use the 3 items above as a key, the answer is to use a Delegate
made up from parts 1 and 2, and then pair a Dictionary
to that.
Or to put as a field initialization:
readonly ConditionalWeakTable<Delegate, Dictionary<object[], object>> cache = new ConditionalWeakTable<Delegate, Dictionary<object[], object>>();
(Also of note is the use of a StructuralEqualityComparer with the above dictionary to make this work).
This of course does everything I want. It will keep track of objects until the referenced object which contains the method (and from which the Delegate
is comprised) is cleaned from memory. At this point, the cached dictionary will also be released as well, clearing out all of its contents.
来源:https://stackoverflow.com/questions/37929406/is-it-possible-to-use-hashcodes-as-a-bitmask-to-efficiently-store-track-collecti