Significant GC performance penalty
SomeDude
lovelydear at mailmetrash.com
Sun Dec 16 13:40:09 PST 2012
On Sunday, 16 December 2012 at 07:47:48 UTC, Rob T wrote:
> On Sunday, 16 December 2012 at 05:37:57 UTC, SomeDude wrote:
>>
>> Isn't the memory management completely negligible when
>> compared to the database access here ?
>
> Here are the details ...
>
> My test run selects and returns 206,085 records with 14 fields
> per record.
>
> With all dynamic memory allocations disabled that are used to
> create the data structure containing the returned rows, a run
> takes 5 seconds. This does not return any data, but it runs
> exactly through all the records in the same way but returns to
> a temporary stack allocated value of appropriate type.
>
> If I disable the GC before the run and re-enable it immediately
> after, it takes 7 seconds. I presume a full 2 seconds are used
> to disable and re-enable the GC which seems like a lot of time.
>
> With all dynamic memory allocations enabled that are used to
> create the data structure containing the returned rows, a run
> takes 28 seconds. In this case, all 206K records are returned
> in a dynamically generate list.
>
> If I disable the GC before the run and re-enable it immediately
> after, it takes 11 seconds. Since a full 2 seconds are used to
> disable and re-enable the GC, then 9 seconds are used, and
> since 5 seconds are used without memory allocations, the
> allocations are using 4 seconds, but I'm doing a lot of
> allocations.
>
> In my case, the structure is dynamically generated by
> allocating each individual field for each record returned, so
> there's 206,085 records x 14 fields = 2,885,190 allocations
> being performed. I can cut the individual allocations down to
> 206,000 by allocating the full record in one shot, however this
> is a stress test designed to work D as hard as possible and
> compare it with an identically stressed C++ version.
>
You cannot expect the GC to perform like manual memory
management. It's a completely unrealistic microbenchmark to
allocate each individual field, even for manual MM. The least you
can do to be a little bit realistic is indeed to allocate one row
at a time. I hope that's what you intend to do. But usually,
database drivers allow the user to tweak the queries and decide
how many rows can be fetched at a time, and it's pretty common to
fetch 50 or 100 rows at a time, meaning one allocation only each
time. It would be interesting to compare the performance of the
two languages in these situations, i.e one row at a time, and 50
rows at a time.
More information about the Digitalmars-d
mailing list