digitalmars.D - memory allocation is slow, why and how to improve
- %u (50/50) Oct 19 2006 I supposed that memory allocation in D should be very fast for it employ...
- Andy Knowles (30/91) Oct 19 2006 When you say memory allocation should be fast, are you referring to just...
- Breezes (5/5) Oct 19 2006 Hi Andy
- Hasan Aljudy (3/8) Oct 19 2006 You can still try the "= void;" initializer for D and get rid of the
- Lionello Lunesu (5/16) Oct 19 2006 Yes, the "=void" and perhaps use "delete" also in D! That would make it
- kawa (9/35) Oct 22 2006 Right, don't use GC if you (moslty) manage memory manually.
I supposed that memory allocation in D should be very fast for it employees GC technique. However, I dit a simple test and found D is slower that C++ and Java. The source file a used in test is listed as follows. == File test.d int main(char[][] args) { for (int i = 0; i < 10000000; i++) { new byte[(i % 128) + 1]; } return 0; } == File test.cpp int main(void) { int i; for (i = 0; i < 10000000; i++) { char *p = new char[(i % 128) + 1]; delete p; } } == File test.java public class test { public static void main(String[] args) { for (int i = 0; i < 10000000; i++) { byte[] a = new byte[(i % 128) + 1]; } } } For test.cpp, I build it with: g++ -O2 test.cpp For test.d, I build it with: dmd -O -release test.d The results are: time java test ; time ./a.out ; time ./test real 0m7.754s user 0m5.688s sys 0m2.048s real 0m11.919s user 0m11.909s sys 0m0.004s real 0m19.256s user 0m19.033s sys 0m0.004s You can see that Java is the fastest, D is the slowest, much slower that C++. My test environment: Hardware: IBM laptop T43 OS: Ubuntu Dapper 6.06 Kernel: 2.6.15-27-386 DMD version: v0.169 g++ version: g++ (GCC) 4.0.3 java version: Sun JVM 1.5.0_06 So what's the reason, and how to improve it?
Oct 19 2006
%u wrote:I supposed that memory allocation in D should be very fast for it employees GC technique. However, I dit a simple test and found D is slower that C++ and Java. The source file a used in test is listed as follows. == File test.d int main(char[][] args) { for (int i = 0; i < 10000000; i++) { new byte[(i % 128) + 1]; } return 0; } == File test.cpp int main(void) { int i; for (i = 0; i < 10000000; i++) { char *p = new char[(i % 128) + 1]; delete p; } } == File test.java public class test { public static void main(String[] args) { for (int i = 0; i < 10000000; i++) { byte[] a = new byte[(i % 128) + 1]; } } } For test.cpp, I build it with: g++ -O2 test.cpp For test.d, I build it with: dmd -O -release test.d The results are: time java test ; time ./a.out ; time ./test real 0m7.754s user 0m5.688s sys 0m2.048s real 0m11.919s user 0m11.909s sys 0m0.004s real 0m19.256s user 0m19.033s sys 0m0.004s You can see that Java is the fastest, D is the slowest, much slower that C++. My test environment: Hardware: IBM laptop T43 OS: Ubuntu Dapper 6.06 Kernel: 2.6.15-27-386 DMD version: v0.169 g++ version: g++ (GCC) 4.0.3 java version: Sun JVM 1.5.0_06 So what's the reason, and how to improve it?When you say memory allocation should be fast, are you referring to just memory allocation or memory allocation and deallocation (memory management)? If you are talking about only memory allocation, you should not be deleting the memory you allocated in C++ and you should be disabling the garbage collector in D and Java. I'm not sure this is possible in Java. If you want to compare memory management, then you should expect D to be slower than C++ because a GC will always be slower than manual memory management in straight forward situations such as the example above. You should also not delete any of the allocated arrays until the end of the loop - the GC in D is very likely not being run until the program exits, so no memory will be freed until this point. So you are allocating from different heaps - one which is reset after each allocation (C++) and one which is not. This will effect your results. And technically, you should be using delete [] p; in C++. Java may be faster than D because the garbage collector is not even called - the program simply exits and leaves cleanup to the OS. This would make it faster than C++ because there is no need to delete. Java probably also has a smarter GC than D. D's GC is not type-aware, so it has to scan the arrays you allocate for pointers to other objects. This is one area where D's GC could be improved. D also initializes allocated arrays where C++ does not. I believe Java does as well but I'm not sure. And last of all, you should be careful constructing examples that do nothing as a clever optomiser will get rid of the parts that cannot possibly have any side effects. I'd be interested to see timing results for more carefully constructed examples. Regards, Andy
Oct 19 2006
Hi Andy Thanks a lot for your quick reply. Definitly I want to test memory allocation and deallocation as a whole. As you have stated, the main problem of my simple test is that it is too simple. I think I should construct a more complex and resonalbe test case.
Oct 19 2006
Breezes wrote:Hi Andy Thanks a lot for your quick reply. Definitly I want to test memory allocation and deallocation as a whole. As you have stated, the main problem of my simple test is that it is too simple. I think I should construct a more complex and resonalbe test case.You can still try the "= void;" initializer for D and get rid of the "delete p;" in C++
Oct 19 2006
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:eh8jrd$3k8$1 digitaldaemon.com...Breezes wrote:Yes, the "=void" and perhaps use "delete" also in D! That would make it somewhat fairer. L.Hi Andy Thanks a lot for your quick reply. Definitly I want to test memory allocation and deallocation as a whole. As you have stated, the main problem of my simple test is that it is too simple. I think I should construct a more complex and resonalbe test case.You can still try the "= void;" initializer for D and get rid of the "delete p;" in C++
Oct 19 2006
Andy Knowles wrote:When you say memory allocation should be fast, are you referring to just memory allocation or memory allocation and deallocation (memory management)? If you are talking about only memory allocation, you should not be deleting the memory you allocated in C++ and you should be disabling the garbage collector in D and Java. I'm not sure this is possible in Java.Right, don't use GC if you (moslty) manage memory manually. You can't turn off GC in Java.Java may be faster than D because the garbage collector is not even called - the program simply exits and leaves cleanup to the OS. This would make it faster than C++ because there is no need to delete.The java VM don't run GC collect on exit (.NET clr do). Add -verbose:gc flagJava probably also has a smarter GC than D. D's GC is not type-aware, so it has to scan the arrays you allocate for pointers to other objects. This is one area where D's GC could be improved.As far as I know D use a conservative GC, being able to have a generational one like Java improve performance in such typical situations.D also initializes allocated arrays where C++ does not. I believe Java does as well but I'm not sure.Java initializes every data so you have to do the same in C++.And last of all, you should be careful constructing examples that do nothing as a clever optomiser will get rid of the parts that cannot possibly have any side effects. I'd be interested to see timing results for more carefully constructed examples.Me too :)Regards, Andy
Oct 22 2006