Hacker News new | ask | show | jobs
by lmilcin 2859 days ago
Hi! I have worked on algorithmic trading framework for third largest Polish brokerage house and I also re-implemented LMAX Disruptor for this project.

Actually, allocating and discarding objects is not the problem. Java allocation and deallocation is extremely efficient for short living objects.

I would say memory layout, access patters resulting from object orientedness are much more important factor.

It is possible to get very close to raw performance, but you have to reinvent almost everything. The code starts looking like plain C very quickly.

2 comments

Information architecture always matters.

But in Java it always seemed that you are very much punished for having data structures that are at cross purposes to your dominant work load. I cut my teeth on implementing the last two parts of “make it work, make it right, make it fast”, often on projects where the existing team had declared that everything that could be done already had been done. There are a lot of refactorings that accomplish both goals, and I often got a 2-3x out of these projects by removing slow tech debt, and more by exposing a real info architecture.

It always surprised me that a language that so punished (especially in the early days where it was interpreted and all object lookups were double indirect) the Big Ball of Mud antipattern exhibited so many examples of it, so frequently.

We can do better. So much better.

On one of the projects I had trouble convincing the company to stay on Java for their application when they were displeased with the performance.

The previous developers were just careless/clueless about performance and when it started becoming a problem they cited good patterns they were following and blamed Java for their problems. The tech lead wanted to rewrite it in C++ which would be suicide IMO.

What I did, I created a graph in a form of horizontal bar which showed color-coded parts of transaction processing. The color codes showed different parts: business logic, frameworks, infrastructure, communication, etc. I then marked a different graph showing which parts of this was unnecessary with some notes of how this can be optimized. You guess, the parts that were not easily optimized away were very hard to find.

In the end we stayed on Java achieving almost two orders of magnitude performance improvement.

Just adding on that this is my experience as well.

Objects usually fell into one of two categories: discarded immediately or held for the entire application lifetime. Anything in between was problematic. Most things ended up using object pools. We also used to never really convert anything from binary format and just used wrapper objects to access the byte arrays directly.

Another sort of trick was scheduling GC for times when the application was OK to pause helped considerably, and made behavior more predictable as well.

It'd be tough to compare it to C/C++ given the complexity of the application. But without giving away specifics, we had solid performance afaik. But you're correct that it does end up making for some interesting Java code.