Closed snaumenko-st closed 2 months ago
Eliminating all remaining string
allocations seems to me much more difficult. As almost half of the code needs to be rewritten from scratch. And of course we don't have convenient support for that in earlier versions of .net.
So this PR is mostly a compromise.
I'm working on a new parser and serializer that uses spans and has 0 allocations, outside the initial buffer. I'm not sure how I'm going to fit it into the existing codebase yet.
@JoshClose Are there any chances that this PR will be concidered / reviewd / merged and then published in near future? We would really like to fix a performance issue in our project that is fixed in this PR. If not, then we would consider creating a fork.
I'll try and get to it soon.
Does this same issue happen when reading?
Does this same issue happen when reading?
No, when reading it's much better, and It allocates only a few bytes per operation.
This has been merged. I made other changes before you put in your second commit, that aren't in there, but I had done the same thing myself. Please look over everything and try it out. I will create a release once you do.
@JoshClose I've tried the same benchmarks, and the results are almost the same, except with ExpandoObject
. However it makes no sense to us.
Thanks a lot!
P.S. My CsvReader
benchmarks before and after your latest fix show almost the same results. So, I'm not sure whether it improved anything.
ExpandoObject
uses IDynamicMetaObjectProvider
so I just removed the ExpandoObject
specific code. Apparently it was faster. I need to do some work on the IDynamicMetaObjectProvider
code to make it faster.
My CsvReader benchmarks before and after your latest fix show almost the same results. So, I'm not sure whether it improved anything.
Maybe not, but there is definitely less computations. Plus, it's consistent with the writer now.
I'll push a new build soon. Just need to update the change log.
I changed expando to use any IDictionary<string, object>
now, so that should cover most dynamics. It'll fall back to IDynamicMetaObjectProvider
, which is slower.
I added a fast dynamic object that is created instead of ExpandoObject
when reading.
This will be in the next release 32.0.0 on NuGet.
I noticed that
CsvWriter
allocated huge amount of memory during serialization, much more than the size of the data, up to 3 orders of magnitude. It doesn't have memory leaks in my scenario, however such memory traffic createsGC
pressure and has noticeable performance impact on my application.There are some breaking changes to the public types though. But they can be easily fixed if needed. I'd also consider to make them internal in further versions to lower the probability of someone uses them directly.
So that's what is implemented here:
GetType()
is called too often.Type
HashCodes. No need to getAssemblyQualifiedName
to get it'sHashCode
, we can get it directly from theType
. However both approaches don't guarantee no collisions.Before
After