digitalmars.D - StructType.init and StructType() cause a allocation
- Benjamin Thaut (32/32) Jun 30 2012 If T is a struct both of the following statements will lead to a call of...
- bearophile (8/11) Jun 30 2012 A similar bug was fixed very recently. D used to allocate a
- bearophile (60/62) Jun 30 2012 I have compiled this code from your issue 7271 with the latest
- Benjamin Thaut (5/66) Jun 30 2012 Thank you, Its very nice to know that this got fixed. Someone might want...
If T is a struct both of the following statements will lead to a call of the _d_arrayliteral function which will allocate a array of the size of the struct just to initialize it!! void T[] data = ...; data[0] = T.init; data[0] = T(); This has proven to be the biggest performance bottleneck in my current codebase, replacing this statement with a unneccessary workaround speeds my code up by factor 100. This is the cause because all of my container classes tend to reinitialize the contents of the data arrays they are holding. Also this bug makes it very hard to write non leaking code when not using a GC. The replacement code could be T temp; data[0] = temp; Which works correctly as long as T is publicly accessible, if it is a private type this will not compile. Then you have to do some more fancy stuff like: void[T.sizeof] temp; void[] initMem = typeid(T).init(); if(initMem.ptr is null) memset(temp.ptr, 0, temp.length); else temp[] = initMem[]; data[0] = *cast(T*)temp.ptr; How hard would it be to fix this? It is really a shame that reinitalizing a struct a) is a major performance bottleneck b) leaks memory I created a bug ticket for this 6 months ago, but it has been ignored so far: http://d.puremagic.com/issues/show_bug.cgi?id=7271 Kind Regards Benjamin Thaut
Jun 30 2012
Benjamin Thaut:I created a bug ticket for this 6 months ago, but it has been ignored so far: http://d.puremagic.com/issues/show_bug.cgi?id=7271A similar bug was fixed very recently. D used to allocate a dynamic array of length 1 when you write "new T" where T is a struct. I don't know if that bug fix (in dmd 2.060alpha) has fixed your problem too. Such kind of bugs do get fixed, eventually :-) Bye, bearophile
Jun 30 2012
I don't know if that bug fix (in dmd 2.060alpha) has fixed your problem too.I have compiled this code from your issue 7271 with the latest beta: struct MemoryBlockInfo { size_t size; long[10] backtrace; int backtraceSize; this(size_t size) { this.size = size; } } void main() { MemoryBlockInfo info; info = MemoryBlockInfo.init; //array allocation here } Compiling it with no optimization it gives: _D4temp15MemoryBlockInfo6__ctorMFkZS4temp15MemoryBlockInfo enter 4,0 mov ECX,8[EBP] mov [EAX],ECX leave ret 4 __Dmain comdat enter 060h,0 push ESI push EDI mov ECX,018h xor EAX,EAX lea EDI,-060h[EBP] rep stosd mov ESI,offset FLAT:_D4temp15MemoryBlockInfo6__initZ lea EDI,-060h[EBP] mov CL,018h rep movsd pop EDI pop ESI leave ret With -O -release -inline it becomes: _D4temp15MemoryBlockInfo6__ctorMFkZS4temp15MemoryBlockInfo comdat push EAX mov ECX,8[ESP] mov [EAX],ECX pop ECX ret 4 __Dmain comdat sub ESP,064h mov ECX,018h xor EAX,EAX push EDI lea EDI,4[ESP] rep stosd pop EDI add ESP,064h ret In both cases I don't see a memory allocation. Bye, bearophile
Jun 30 2012
Am 30.06.2012 13:52, schrieb bearophile:Thank you, Its very nice to know that this got fixed. Someone might want to close the ticket as duplicate then. Kind Regards Benjamin ThautI don't know if that bug fix (in dmd 2.060alpha) has fixed your problem too.I have compiled this code from your issue 7271 with the latest beta: struct MemoryBlockInfo { size_t size; long[10] backtrace; int backtraceSize; this(size_t size) { this.size = size; } } void main() { MemoryBlockInfo info; info = MemoryBlockInfo.init; //array allocation here } Compiling it with no optimization it gives: _D4temp15MemoryBlockInfo6__ctorMFkZS4temp15MemoryBlockInfo enter 4,0 mov ECX,8[EBP] mov [EAX],ECX leave ret 4 __Dmain comdat enter 060h,0 push ESI push EDI mov ECX,018h xor EAX,EAX lea EDI,-060h[EBP] rep stosd mov ESI,offset FLAT:_D4temp15MemoryBlockInfo6__initZ lea EDI,-060h[EBP] mov CL,018h rep movsd pop EDI pop ESI leave ret With -O -release -inline it becomes: _D4temp15MemoryBlockInfo6__ctorMFkZS4temp15MemoryBlockInfo comdat push EAX mov ECX,8[ESP] mov [EAX],ECX pop ECX ret 4 __Dmain comdat sub ESP,064h mov ECX,018h xor EAX,EAX push EDI lea EDI,4[ESP] rep stosd pop EDI add ESP,064h ret In both cases I don't see a memory allocation. Bye, bearophile
Jun 30 2012