3 ms·
"One way to get C-like performance is to use C via JNI for key sections of code. If you want to avoid using C or JNI there are still ways you can get the perfor
by nvarsj 15y ago
"One way to get C-like performance is to use C via JNI for key sections of code. If you want to avoid using C or JNI there are still ways you can get the performance you want."
JNI has huge latency. Write code in Java to get "C-like" performance.
"One area Java can be slower is array access. This is because it implicitly does bounds checking."
Which gets optimized away by hotspot.
"However this doesn't mean you can't pre-allocate your objects, use Direct ByteBuffers and Object recycling techniques to minimise your object creation."
Please don't write your own object pools, this isn't 1995.
- srean 15y ago> Which gets optimized away by hotspot. I believe it would do so automatically only when it can prove that the bound will not be violated. That wouldnt be very often in a program written in an imperative style. Lest it be mistaken for a swipe at imperative style, functional languages don't have it much easier either. I think the problem is that for the most part, array use patterns are not very amenable to this kind of analysis. So even in functional languages you have to explicitly ask the runtime or the compiler to avoid bound-checks. If I remember correctly, there were a few languages designed to handle this case, i.e. use compile time type-checking to ensure that all the arrays are of the right shape and that none are accessed un-safely. Fish I think is what it was called. Dont know what happened to it or the idea. Seemed pretty handy to have. I think the first place to check now would be SAC (single assignment C). But I have digressed far from the topic of this thread ! > Please don't write your own object pools, this isn't 1995. The snark was unnecessary. It is frowned upon here.
- krakensden 15y ago> > Please don't write your own object pools, this isn't 1995. > The snark was unnecessary. It is frowned upon here. Plus he's wrong, especially for all the people writing GUI applications who want to avoid GC pauses (for Dalvik, not the JVM, but still).
- davidtgoldblatt 15y agoOn the contrary, for almost all types of common array code the compiler is really good at optimizing away the bounds checks (see http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.86.9658 http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.86.96... ). Things only get tricky when you have, for instance, arrays of indices into other arrays, or when the next array position to examine depends on the contents of the one being examined. Even there though (and even in array-heavy code), bounds checks don't typically take up a ton of program execution time.
- srean 15y agoFor sparse matrix operations that is the most common pattern of access though. For linear algebraic operations on dense matrices, BLAS and LAPACK takes care of most of the issues and is super fast. I think the times I do not use BLAS/LAPACK (directly or indirectly) are when I have to apply operations on matrices that are not the typical linear algebraic operations. This comes up fairly often too in my line of work which is machine learning.
- gaius 15y agoSorry to link to a Martin Fowler article, but that is what people are doing now: http://martinfowler.com/articles/lmax.html http://martinfowler.com/articles/lmax.html
- svx 15y agoInteresting, I hadn't seen his article on LMAX. For more details (and the code) check out their google code page: http://code.google.com/p/disruptor http://code.google.com/p/disruptor. The disruptor pattern itself was new to me but the general principles (particularly the idea of running trading business logic in a single thread with all data in memory and no garbage collection) is very familiar.
- gaius 15y agoIt's a silly name for a Pattern. All the others - Command, Strategy, Visitor, etc are more-or-less meaningful. In another blog post, they say they named it after the weapon in Star Trek. They could have called it Ring, because at the end of the day it is just a ring buffer.
- bermanoid 15y agoPlease don't write your own object pools, this isn't 1995. In my experience, object pooling (and poor-man's-object-pooling, using scratch objects and the like) can still make a major difference for certain applications. I worked on JBox2d, a physics engine (which creates a ton of tiny Vec2 objects for intermediate steps in calculations), and for most of its history the highest ROI optimization has been to chip away at any and all unnecessary object creation; sometimes this meant inlining simple operations that would have created intermediate vectors or matrices (this can be a huge win because you both avoid GC load and object-size overhead, which for a cache-miss dominated application like a physics engine can be extremely important), sometimes it meant pre-allocating "scratchpad" objects, and so on, but the end result was that we got more than a 4x speed increase by focusing exclusively on getting rid of small object shenanigans. Recently there was a rewrite which included some more explicit pooling strategies; I haven't tested those against the unpooled variants, but I should, I suspect there's still a huge benefit. The additional bonus is that if you're careful about garbage it's a lot easier to use your code on Android or to push it through GWT, as those platforms don't have anywhere near the GC efficiency of the Sun JVM. I don't know about ByteBuffers, though, we never experimented with those because we didn't want to mess around with any unsafe code that might not be allowed in applets or on other platforms. Things like escape analysis and scalar replacement help, but not enough. The problem is, those optimizations are extremely fragile, and for a lot of real world code the type of analysis required to figure out that those optimizations depends on knowledge of the overall design of the system (for instance, knowing that certain methods will not mutate fields of objects passed to them in certain situations). Granted, a physics engine that's creating ~100,000 small objects per frame in some situations is an extreme edge case, and when I'm not doing that type of programming I'm much less concerned with garbage.