Settings

Theme

You could have invented the LMAX Disruptor, if only you were limited enough

hmijailblog.blogspot.com

42 points by hmijail 7 years ago · 29 comments

Reader

jandrese 7 years ago

What this says to me is that Java's reputation for sluggishness is a result of its idiomatic coding styles more than the language itself. In particular the casual way people allocate and discard objects for everything they do.

If you program it like it was C then you can get good performance, which make sense given that the language was built for embedded devices with anemic processors. Of course you undoubtedly give up some maintainability when you do that, but the tradeoff is getting 6 million packets through the thing per second.

This would also explain why Java benchmarks so well but still tends to be slow in the real world.

  • wmfiv 7 years ago

    Java's reputation for sluggishness was really formed based on people's experience with Applets and Swing applications and especially badly written Applets and Swing applications.

    Java in the real world is fast. That's why it's used as the backbone of so many large organizations and so many scale out solutions (Cassandra, Kafka, Hadoop, etc) are written in Java.

    • pjc50 7 years ago

      Yes, I'd take this in conjunction with https://news.ycombinator.com/item?id=17824575 : "language speed" and "UI responsiveness" are only loosely related, and there are so many ways to end up wasting time blocking or locking without really realising it.

    • mindslight 7 years ago

      > Java's reputation for sluggishness was really formed based on people's experience with Applets and Swing applications

      ... and contemporary interactive performance.

          python    < /dev/null  0.01s user 0.01s system  96% cpu   0.025 total
          racket    < /dev/null  0.17s user 0.02s system  98% cpu   0.198 total
      
          java                   0.09s user 0.02s system  94% cpu   0.118 total
          clojure   < /dev/null  2.07s user 0.06s system 170% cpu   1.247 total
      
      There's of course a theoretical point about being shoehorned into the UNIX execution model, and if Java were able to run as a persistent OS (eg nailgun or whatever it is these days) then things get much better. But still, when you start off a project having to suffer and design workarounds for the language's and implementation's flaws...
    • hmijailOP 7 years ago

      (Author here)

      But that's not "Java in the real world". If anything I'd presume that that's "well programmed Java".

  • lmilcin 7 years 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.

    • hinkley 7 years ago

      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.

      • lmilcin 7 years ago

        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.

    • latencyloser 7 years ago

      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.

  • PaulHoule 7 years ago

    C was built for a minicomputer which might or might not be the brains of a phone switch, a software development environment, a word processing cluster for a newspaper, industrial control for a steel mill, etc.

    The thing about Java is that it has promised and delivered a much better threading experience than other programming languages. When somebody proved the Java memory model was unsafe, Sun fixed it. C and other languages have adopted essentially this memory model but a decade and a half later. Java provides bulletproof tools in forms of Executors, Latches and other specialized concurrency constructs. It takes time to learn to use them, but you can ship fast and correct code for something like the LMAX Disruptor.

    • hmijailOP 7 years ago

      (Author here)

      Actually, I think that talking about Java's multithreading here is a red herring; note that LMAX had to abandon multi-threading because it was destroying performance.

      And this is important, because they explicitly made a very interesting point of current architectures being at odds with current thinking about best practices for concurrent programming.

  • aidenn0 7 years ago

    The other thing is that the JVM was sluggish when Java was at peak hype. The steady performance improvements in the decades since have made a big difference.

  • maaaats 7 years ago

    > but still tends to be slow in the real world

    Is it, though?

    • flipp3r 7 years ago

      It's not, but this is a thing people have said since the early days of Java which is still going around the internet. I personally use Java every day and have yet to hear someone complain about the speed of our backends.

      The Techempower benchmarks are a great "real world" example IMO: https://www.techempower.com/benchmarks/#section=data-r16&hw=...

      • coldtea 7 years ago

        >It's not, but this is a thing people have said since the early days of Java which is still going around the internet. I personally use Java every day and have yet to hear someone complain about the speed of our backends.

        That's because for backends it doesn't matter. The DB layer or network will hide any slowdown anyway.

        But for Desktop apps the latency due to GUI overhead and GC pauses can be from mildly annoying to unbearable.

        • jerven 7 years ago

          Sorry, but backends speed does matter. Not every backend is DB connection limited. Faster elasticsearch/solr/lucene etc... is very welcome.

    • jandrese 7 years ago

      Every time I fire up an Apache Tomcat and it burns several gigabytes of memory to somehow run a simple web service very slowly...

      A more famous example might be Minecraft, where even with its blocky graphics it can tax a high end gaming machine when you turn the view distance up to a range that almost no other engine would consider long. The engine has been rewritten in other languages where it is much faster, notably the Microsoft version and the Phone version.

      • jandrese 7 years ago

        Isn't the memory use itself a big problem on modern architectures? Or has it gotten better lately since CPU clocks have been relatively flat and memory clocks have been creeping up? The problem with the "allocate-and-discard" model of programming in the past is that it thrashes the hell out of the cache, which means lots of trips to main memory, which is slow on modern machines.

        When you get an article like this going "holy shit, where have you been all my life circular buffers" it emphasizes the point. You wanna go fast you have to avoid invalidating cache as much as possible.

      • dagenix 7 years ago

        It doesn't sound like you understand how memory Management in Java works. In Java, you have a defined heap size. Java will claim memory in order to support that heap. If you are unhappy about how much memory it is using, you can change the heap size.

      • tomaha 7 years ago

        Memory usage is still terrible with Java but at least there are plans to address part of it with value types etc. But for a web service performance is pretty good (just look at techempower benchmarks and the fact that most high scale companies use Java for a significant part of their infrastructure). If you need to talk about startup time you don't need scalablitiy or really want a different solution/architecture.

  • hmijailOP 7 years ago

    (Author here)

    "If you program it like it was C then you can get good performance" -> Note that one of the points of the post is that just using "like C" won't magically fix your performance!

    If anything, you could say "If you program it like a system with limited memory then you can get good performance". That, I can imagine being a universally applicable thing.

    My point is that, for example for the particular case of memory management, there is an associated cost, whatever your language is; and you need to deal with it. Ignorance of the law is no excuse, etc.

  • blt 7 years ago

    The lack of value semantics for composite types is a huge problem in the language itself. It is often hard to get a Java program to have the same memory layout you would get writing idiomatic C/C++.

  • igorlev 7 years ago

    Slow, in this context, is too much of a vague term. Are we talking about latency? Throughput? GC pauses? UI sluggishness? VM startup speed?

draw_down 7 years ago

This is the kind of thing I really love reading. It’s ostensibly about a technical subject, but that’s really a jumping-off point for examining how we think and talk about things, how portions of our field become Balkanized, how what we encounter shapes our sense of what’s possible and ultimately hardens into “common knowledge”.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection