4 ms·
As could be expected, this just benchmarks the implementation. For instance, Perl has lots of object creation while C uses a fast state-machine-like approach.
by JoachimSchipper 16y ago
As could be expected, this just benchmarks the implementation. For instance, Perl has lots of object creation while C uses a fast state-machine-like approach.
Don't get me wrong - I really like C - but I'm not even sure that it would still be faster than Perl if you switched implementations.
- fleitz 16y agoAgreed. Sure in scala there are a couple things you can't do like pointer manipulation, so you are going to incur more allocations but from what I've found in C# is, if you code it like a C app it performs like a C app. The biggest key to performance I've found in managed code is to not allocate memory. It reduces stress on the GC, and improves your cache hit rate.
- barrkel 16y agoI can't agree with the non-allocation of memory. What you don't want to do is create garbage that doesn't die until after a collection has already occurred - this is the mid-life crisis problem. But you shouldn't be unduly afraid of allocating memory which won't last long. I wrote up a quick test sample: http://pastebin.com/YmbT08Uy http://pastebin.com/YmbT08Uy All it does is fill in an array with values from 0 to 511, then sum them up. The catch is that it zeros out the array before filling in the values, in two different ways: one (P), by re-using an array, and secondly (Q) by reallocating the array and letting the garbage collector zero it out. Here are test run timings: P: 8.749 Q: 7.070 Result: 0 And in reversed order, to show that order of compilation didn't make a difference: Q: 7.081 P: 8.746 Result: 0 The code using the GC to implicitly zero out the array is still faster than the code that reuses the array, even though the GC is having to collect a large fraction of the 10 million 2048-byte arrays allocated by Q. P, on the other hand, only allocates 100 of them. Test machine: i7 920 @ 3.6GHz, 12GB memory, .NET 4 on Win7 64-bit. Don't forget that time spent in GC is proportional to the amount of live data in the generation(s) being collected, not the amount of garbage. Collecting garbage is actually free; it's finding out what's garbage that costs. If you don't keep references around to memory (i.e. increase your live set), GC is very cheap.
- runT1ME 16y agoVery well said, and I believe what makes the G1 so brilliant is it will be able to tackle the mid-life crisis issue.
- JoachimSchipper 16y agoI'm by no means an expert on the .Net platform, but are these equivalent? You generate ~20GB of garbage, about half of which could comfortably fit in your memory; more importantly, it appears that .Net, in some modes, does garbage collection in a different thread than the one running the program. And it's clear that using a different thread to zero memory is faster... Also note that I was talking about object creation, which may be a lot heavier than array creation.
- barrkel 16y agoThe memory usage never climbs above 15MB - that's for the whole process, the .NET runtime, code, system DLLs, etc. all in. With object creation, reuse is far harder whereas with an array, you can just zero it out. In other words, the argument in favour of reuse is even weaker for objects than it is for arrays. I would say that if you have large arrays - large enough to go into .NET's large object heap, at about 70K - you're better off reusing those, because they only get collected during expensive gen2 collections, and they aren't compacted. As to the fact that the GC can zero memory on a different thread, that's not a problem - it's a benefit, as it's guaranteed correct concurrent zeroing, as opposed to the contortions you'd have to do to reuse. Again, an argument in favour of GC.
- JoachimSchipper 16y agoI was never arguing in favour of reuse; I was arguing in favour of the C approach (keep everything in local variables and build a state machine.) And yes, concurrent zeroing is nice. I don't dispute that: I just wanted to point out that the speedup you demonstrate above (partially) comes from using additional resources (CPU time on another processor), not from using existing resources more efficiently.