ImTools
ImTools copied to clipboard
ImHashMap<int, SampleClass> vs MemoryOwner<SampleClass>
Hello,
for my specific project I should be able to use int type as key, therefore I decided to compare ImHashMap and MemoryOwner and what I got surprised me:
BenchmarkProject.zip
I was expecting MemoryOwner to be faster and better in terms of allocation, but I was not prepared for such big difference. So, I'm wondering if I have used ImTools library in the wrong way.
I feel like just using what seems to be the obvious choice is not a guarantee that could be the right choice. So I would like to know what a very skilled and talented developer like you would choose based on the following:
- A source generator will run at each compilation and will allows me to map keys into int and calculate the exact buffer size needed.
- The value is a class that store delegates and closures. This means that every while I will have to clear some of the values in order to allow GC. At runtime, with ImTools I can delete and add again the whole entry as needed. With MemoryOwner I'm not sure is possible to resize without performing a full reallocation (ex. if a value is mapped to index 9, that index must be always available for that value because I could need to add that value again). I'm unable to determine the impact on memory usage.
- I will keep only one static (and lazy loaded) instance of the collection, therefore its lifetime will be the same of the application
- The collection is mainly used to cache lambda delegates (Func and Action). I'm unable to estimate an exact size, but how many lambda delegates can use an application? 10, 50, 1000?
I initially tried with ImHashMap<Type, Type> and I was surprised on how ImTools performed compared to other solutions. No mapping needed, no source generators needed and no waste of memory. However when I tried to use int keys, I saw a big increase in performance which became gigantic with MemoryOwner and now I'm in doubt on what could be the best solution. I feel like they boths have their pro and con which I'm unable to estimate in order to take an informed decision.
Your help would be really appreciated.
Thanks
@netcorefan1 Hi, could you share the Program.cs and csproj through the gist and not through the zip archive?
Also, I am not sure what is the MemoryOwner you are talking about - is it the ArrayPool wrapper? Then how it can be used as a map?
@netcorefan1 Hi, could you share the Program.cs and csproj through the gist and not through the zip archive?
Many thanks for your support. Gist link
Also, I am not sure what is the MemoryOwner you are talking about - is it the ArrayPool wrapper?
Yes, it is the ArrayPool wrapper made by the community toolkit.
Then how it can be used as a map?
This is something that I really don't have any idea (I don't have the required low level knowledge). It is very uncommon, but someone seems to have done something similar with good results. I have excluded such possibility from the beginning and rather I focused on trying to understand what between the two options could provide faster data access with less resources. There are also other operations which will probably work better with a map, but I'm at the beginning and so I can't do any estimation. So I decided to first focus on performance and check if I have done something wrong for getting so poor performance.
@netcorefan1
I have added the benchmark.
You are comparing different things here:
MemoryOwner.Spanis the pre-allocated Array,ImHashMapis the Map/Dictionary- Moreover,
ImHashMapis the immutable map (e.g. targeting the thread safety scenarios, non-locking, etc.), and making them faster and less memory consuming than the Immutable collections from the BCL.
Next version of ImTools will provide non thread safe map but faster and lighter, called SmallMap which beats the BCL Dictionary (but not the arrays).
closing