Live data from Hacker News

GC Tuning Confessions of a Performance Engineer

slideshare.net

91–98 of 98 posts

Re: GC Tuning Confessions of a Performance Engineer

#91
post #89

Earlier quoted context omitted.

Look man, I don't know what to tell you except that you view code fundamentally differently. My point is that yes, obviously everything gets turned into x64/x86 assembly at some point, and that yes, I'm sure seeing it is very easy. But if I need to prevent a GC pause from happening at some point in the frame my hands are tied. Debating this is like pulling teeth, and I'm inclined to say that if you can't follow at th…

This whole thread started by my statement that I haven't seen large projects without errors doing manual memory management. I doubt very seriously that anyone can write code in large teams where Valgrind will state there aren't double frees, bad frees, or dangling pointers happening. Or a run with Coverity will state everything is nice and shinning. Once upon a time I had to write a tool in a well known particle acce…

Dangling resources are common in any language. Ports don't get reclaimed, file descriptors are opened and never closed... the same principles apply.

Its funny since I actually started writing code for particle accelerator research as well, although it was a mixture of terrible C and F77. Physicists and mathematicians are good at their respective fields, but not necessarily coding sadly (I used to be both). Would the code have been better with a different language? Doubtful. They used literally zero established patterns and wrote everything with copy paste and with zero regard for what the machine actually did.

To each their own though. I'm glad your projects and line of work afford you the ability to work with a GC. Mine do not.

Re: GC Tuning Confessions of a Performance Engineer

#92

Earlier quoted context omitted.

Agreed. Sometimes, you don't even need RAII. You just let the stack unwind :) But yes, RAII can make it pretty braindead (which is good)

Do you have any book suggestions for learning modern C++ memory management techniques? I'm beginning to think maybe it's time to fill that gap in my programming knowledge.

Hmm, modern C++ memory management is not entirely different from before. You have std::unique_ptr which is a game changer. I recommend just learning the language itself well. The C++ Primer (latest edition) plus Effective Modern C++ would be a good start. Also, read that doc floating around about everything a programmer needs to know about memory.

Re: GC Tuning Confessions of a Performance Engineer

#93
post #82
post #70

Earlier quoted context omitted.

Ok, we keep talking about malloc -- which malloc impl are you specifically referring to? There are many allocators out there these days, so let's be a bit more concrete. If not specific name, at least the class of allocator. Most of the common ones you'll find support thread-local allocation buffers, for starters. >Sure, it is rare in "well written applications", but how costly is it to write a well-written applicati…

> Most of the common ones you'll find support thread-local allocation buffers, for starters. And what about concurrent deallocation? > Have you, for example, looked at how postgresql manages memory? sqlite? redis? memcached? Not too well (basically lots and lots of locking, much of it is very coarse-grained). Our spatial in-memory Java database (SpaceBase) offers an order-of-magnitude better performance in concurrent…

> But even for less super-concurrent databases, C++ databases don't outperform Java ones. In this benchmark, the Java databases (H2 and HSQLDB) almost always outperform MySQL and Postgres: http://www.h2database.com/html/performance.html (and I don't even know how the Java solutions handle concurrency, whether they do locking, optimistic locking or a clever combination, like SpaceBase).

It's hardly surprising that a vendor's own benchmark shows it as winning against the competition.

Re: GC Tuning Confessions of a Performance Engineer

#94
post #82

Earlier quoted context omitted.

> Most of the common ones you'll find support thread-local allocation buffers, for starters. And what about concurrent deallocation? > Have you, for example, looked at how postgresql manages memory? sqlite? redis? memcached? Not too well (basically lots and lots of locking, much of it is very coarse-grained). Our spatial in-memory Java database (SpaceBase) offers an order-of-magnitude better performance in concurrent…

> But even for less super-concurrent databases, C++ databases don't outperform Java ones. In this benchmark, the Java databases (H2 and HSQLDB) almost always outperform MySQL and Postgres: http://www.h2database.com/html/performance.html (and I don't even know how the Java solutions handle concurrency, whether they do locking, optimistic locking or a clever combination, like SpaceBase). It's hardly surprising that a v…

Let's suppose for a second that the numbers are biased in the Java databases' favor. I doubt that other benchmarks would show such dramatically different results that would have those databases losing by much. So maybe they're not ahead as those number show (though I have little reason to doubt them), but a little behind. The difference would still not justify the claim that C++ provides superior performance for databases.

Also, it's an open source database with no commercial support by the authors, so I wouldn't really call them "vendors".

Re: GC Tuning Confessions of a Performance Engineer

#95
post #82

Earlier quoted context omitted.

> Most of the common ones you'll find support thread-local allocation buffers, for starters. And what about concurrent deallocation? > Have you, for example, looked at how postgresql manages memory? sqlite? redis? memcached? Not too well (basically lots and lots of locking, much of it is very coarse-grained). Our spatial in-memory Java database (SpaceBase) offers an order-of-magnitude better performance in concurrent…

> But even for less super-concurrent databases, C++ databases don't outperform Java ones. In this benchmark, the Java databases (H2 and HSQLDB) almost always outperform MySQL and Postgres: http://www.h2database.com/html/performance.html (and I don't even know how the Java solutions handle concurrency, whether they do locking, optimistic locking or a clever combination, like SpaceBase). It's hardly surprising that a v…

Let's suppose for a second that the numbers are biased in the Java databases' favor. I doubt that other benchmarks would show such dramatically different results that would have those databases losing by much. So maybe they're not ahead as those number show (though I have little reason to doubt them), but a little behind. The difference would still not justify the claim that C++ provides superior performance for databases.

Also, it's an open source database with no commercial support by the authors, so I wouldn't really call them "vendors".

Re: GC Tuning Confessions of a Performance Engineer

#96

Earlier quoted context omitted.

Specifically about ArrayList -- there are specifically a bunch of projects (Goldman Sachs Collections, trove, FastUtil, Koloboke) that solve the array of primitives problem. I would say that's a Java-standard-libary-specific problem.

And then you have to do a copy just to pass it around to any other external libraries. And you lose the advantages of generics. You end up with 9 copies of everything, that are 99% the same except for a couple find-replaces. If not more. (For instance, if you have a method that takes two generic arrays, you need 81 copies! Even if they are the same type you still need 36 (!) copies.) Not a good solution.

How do you end up with 9 copies of everything? I'm not sure I follow that.

If you are passing in massive ArrayList lists to external libraries, you need to re-evaluate what you're doing. What will that external library do with this?

Re: GC Tuning Confessions of a Performance Engineer

#97

Earlier quoted context omitted.

And then you have to do a copy just to pass it around to any other external libraries. And you lose the advantages of generics. You end up with 9 copies of everything, that are 99% the same except for a couple find-replaces. If not more. (For instance, if you have a method that takes two generic arrays, you need 81 copies! Even if they are the same type you still need 36 (!) copies.) Not a good solution.

How do you end up with 9 copies of everything? I'm not sure I follow that. If you are passing in massive ArrayList lists to external libraries, you need to re-evaluate what you're doing. What will that external library do with this?

Look at java.util.Arrays for a concrete example of the problem:

    static int 	binarySearch(byte[] a, byte key)
    static int 	binarySearch(char[] a, char key)
    static int 	binarySearch(double[] a, double key)
    static int 	binarySearch(float[] a, float key)
    static int 	binarySearch(int[] a, int key)
    static int 	binarySearch(long[] a, long key)
    static int 	binarySearch(Object[] a, Object key) 
    static int 	binarySearch(short[] a, short key)
This, sort of works. It's a lot of code duplication, but it's all in the library.

Except that a relatively common thread goes like this:

You start by having a generic array that gets passed to said binary search. It works, but it's too memory-hungry when it gets called with a primitive. So, then what do you do?

Well, you go "huh, I could specialize". And then you start specializing, and realize that every function that calls binarySearch with a generic type also needs 8 implementations (would be 9, but no sane person would binary search a boolean[] ).

Basically, its complexity that you cannot even punt off to an external library. If you have code that needs to be able to be called with generics without inefficiencies for primitive types, you'll end up with ~9x code duplication at a minimum.

Re: GC Tuning Confessions of a Performance Engineer

#98
post #16

Earlier quoted context omitted.

Not to mention that you get to hire performance engineers . People may have overestimated their utility (that they are good for less things then commonly thought). Maybe not to the degree that the stereotypical C/++ would believe, but still an overestimation. Maybe we just need to use more abstractions in the middle between manual and fully automatic memory management, like region-based memory management (just an exa…

I think the solution is to use the right memory management tool for the job. pron is right that GC can be helpful for concurrent data structures (where the non-GC approach, hazard pointers, is basically just a GC), for instance. GC is also great when your objects have truly dynamic lifetime, such as open files in Unix from the kernel's point of view. But GC for all data tends to be overkill when your goal is to maxim…

> I think the solution is to use the right memory management tool for the job.

That's like a generalization of my own argument. Generalized to the point where we are in the domain of truisms like "right tool for the job" (as opposed to what, the wrong tool for the job?).

Post reply on HN