So Scala or Clojure it is? Honestly, I am starting to learn Java as a very amateur programmer and this is over my head.
Are the other JVM languages actually doing better as they were architected differently from their core, the models for parallelism and/or concurrency is different, both? I would love to hear comments from those more educated than I in JVM esoterics (although I would say the money involved it is worth knowing).
By default, Scala's parallel collections use fork/join on JVMs > 6, so using Scala probably isn't going to change much for you.[1]
Also, note that this guy's company makes software that directly competes with the JVM's fork/join framework, so he's not exactly an unbiased source.[2]
The way this problems change in Scala is not by using the parallel collections library, but by using Akka straight up, or using Spark.
Akka is an actor system framework, so it's extremely well suited for this problem.
Spark can process tremendous amounts of data in parallel, even over hundreds of machines if you really have the iron, and works just as well with just one machine.
You can technically use them both from Java, but being natively Scala libraries, you are really better off switching to Scala if you are going to use them.
Indeed, the Akka team published an blog post [1] a while back that demonstrates superior performance versus a traditional thread pool. The actor model seems to be a very favorable use case for F/J though.
If you're an amateur programmer then you probably don't have to worry about this. Just be aware that threading is complicated. Don't go looking for languages to solve problems you don't have just because of a blog post.
On the other hand, as a Lisp is the True Way type, I believe there are very good reasons to learn a Lisp early in your study of programming. While Scheme has a lot going for it in this domain, Clojure is not bad at all, and it happens to have a lot of good solutions for concurrent programming.
Everyone should learn a Lisp early in their career. Anyone who actually cares about performance will learn quickly that auto-parallelizing or 'parallel collections/streams' is a joke, with Amdahl's law being the punchline.
Don't worry, done and done. I play with Common Lisp on my machine, and I definitely dream of writing a web app in Clojure and Clojurescript once I finish some Java coursework. Things will slow down and I will understand the underlying Java/JVMisms as well as bonus. (Taking Java for school reqs, not for this reason of course, but it would be nice.)
I wanted to get back into programming largely bc of what I read here and on my collection of programming Reddits. So much interesting and beautiful stuff.
And I know the increasing popularity of the JVM (if it ever wanted), is that the JVM primitives allow for some threading, which means parallel/concurrent use of processors cores at all. Seeing as people whine about Python and Ruby and GIL, native threads have to be found somewhere while also offering the own risks.
But thanks, I like this site because I can get a programmer's education in "what I worry about and what to avoid unless I am ready" while I learn, not after.
It's noticeable that some companies are switching back from Scala to Java e.g. LinkedIn, Yammer and after using it for a while it's not hard to see why. It's awfully complex and obtuse in many parts.
Clojure simply isn't that popular and likely won't be.
Fan and user of Clojure here :). It's a Lisp and popular enough to use safely and if you don't mind the syntax, go for it. You find it used in all those companies in small projects, so these companies are always looking for engineers who would also be comfortable in it.
The Yammer switch happened quite a while ago. The language now is more stable and performant. Other than these two isolated incidents, there isn't really anything to "notice".
Scala gives you nice options around managing concurrency; it's explicit but not verbose, and you end up writing code that uses general techniques that apply to other cross-cutting concerns rather than being concurrency-specific. Another reply points out that the default pool is a Java fork-join pool - but it's a 1-liner to change that if you want.
(I have no connection with any selling of concurrency solutions; I use scala (including spark and scalaz-stream) professionally)
Does anyone else think like this article is written in a bombastic, obfuscatory style? I feel like the author is more concerned about communicating how very intelligent he is than warning other developers about the dangers of fork-join frameworks. Who is he trying to impress?
Between on the author's explicit trademark annotations, division of the world into "junior", "senior", and "architect", pretentious grammatical hypercorrection[1], and casual dismissal of sun.misc.Unsafe use, I think I'd hate working with the him.
[1] Why the fuck am I supposed to trust someone who doesn't understand the distinction between "it's" and "its" to tell me that all of Oracle's language designers got a core piece of infrastructure irrecoverably wrong?
Java's parallel stream is a cool feature, but it's suitable only for small batches of data.
Once i tried streams with lambdas to process a large corpus of data (processing many items in a multi-stage manner). While the code was clean and nice, the performance was horrible. A lot of thread waits, etc. Much worse than handling the whole process on my own with thread pools.
Also there are many catches: for instance, when you start your stream with 1 item there will be only max 1 parallel thread to handle the data, and it doesn't matter if you do some fancy data split on some stage of the stream.
In terms of performance you really need to minimize contention. If you build something that sends things round-robin to different spliterators you are going to have horrible performance, you really need to batch 10,000 or so lines and send those to different spliterators.
Also for anything that is pipelined there is ultimately going to be a bottleneck at the weakest point, which could be the spliterator factory.
I don't necessarily agree ... parallel streams can handle immense amounts of data if they're processing a suitable data set. The problem that's being described was prevalent when threads were being created manually too. Like anything else, the tool needs to be matched to the job. We processed about 32E9 pieces of telemetry per day ... our parallel threads were normalizing and aggregating that data as well as preparing it for storage.
If you have too many threads waiting, you've got too many threads. I did a significant amount of testing using threads (on a project I can't share) and found that generically, you should have n + 1 threads when you have n processor cores. If your processor I/O bandwidth is limited, you may find better performance with less processors.
If you're creating something like a tick-store (Michael Stonebraker - newest Turing award winner), you'll need to tune the rest of the system to feed the processors data at the maximum rate too. We were using E15K (and another bigger machine I can't remember) and used processor affinity to make sure all but 3 of the processors were dedicated to parallel threads. The thread count was the number of dedicated processors plus one.
Having too many threads leads to context churn ... think about what you're trying to accomplish and design the system appropriately. And of course, some problems need other solutions.
First and foremost: I’m a programmer, not a web site developer or professional author. If you don’t like my web site or writing style, too bad. The explicit trademark specification came from legal advice. If you want to criticize something I do well, then criticize my software. I maintain tree active open-source products on SourceForge:
The grist of the three articles is
1. This framework doesn’t belong in core Java.
2. This framework should not be the parallel engine that drives all parallel computing (streams etc.) in Java.
3. It is still failing as a parallel engine no matter what the engineers do.
A little history may help.
In 2010, I submitted a proof-of-concept to the good professor showing that scatter-gather works just as well as what he was proposing for Java7. Since he ignored the proof completely, I took the parallel engine out of a Task Parallel product I maintain and put in the Data Parallel engine. This product is also open-source. It is not suitable for an API since it is a full feature Data Parallel product. It is not for sale. It is, and has always been, open-source. Data Parallel only works well on copious processors, which is why I never bothered offering it before.
The software examples I submitted with the articles (downloadable) are sufficient to prove my points. These are not full benchmarks since that isn’t necessary for an article; they prove the point – sequential is usually faster than the parallel version, etc.
There are seventeen points in the first two articles. Not one person has ever said, “Hey Ed, that’s not true.” The points are accurate. There is no B.S. in any of the articles. I may not have the eloquent style of a professional author (yes I am a little blunt, what else do you expect from a programmer) but I did the best I could. If you want to throw eggs at them, fine. At least be specific about which point you think is wrong.
Intel has TBB. Microsoft TPL. If Java wants a parallel engine then they should have copied the others. Using an academic centric product that is based on dyadic recursive division is not the way into the parallel future for Java.
31 comments
[ 3.2 ms ] story [ 81.4 ms ] threadAre the other JVM languages actually doing better as they were architected differently from their core, the models for parallelism and/or concurrency is different, both? I would love to hear comments from those more educated than I in JVM esoterics (although I would say the money involved it is worth knowing).
Also, note that this guy's company makes software that directly competes with the JVM's fork/join framework, so he's not exactly an unbiased source.[2]
[1] http://docs.scala-lang.org/overviews/parallel-collections/co...
[2] http://www.coopsoft.com/Products.html
Akka is an actor system framework, so it's extremely well suited for this problem.
Spark can process tremendous amounts of data in parallel, even over hundreds of machines if you really have the iron, and works just as well with just one machine.
You can technically use them both from Java, but being natively Scala libraries, you are really better off switching to Scala if you are going to use them.
[1] http://letitcrash.com/post/17607272336/scalability-of-fork-j...
And I know the increasing popularity of the JVM (if it ever wanted), is that the JVM primitives allow for some threading, which means parallel/concurrent use of processors cores at all. Seeing as people whine about Python and Ruby and GIL, native threads have to be found somewhere while also offering the own risks.
But thanks, I like this site because I can get a programmer's education in "what I worry about and what to avoid unless I am ready" while I learn, not after.
In what concerns the typical enterprise, the JVMs and Android are all about Java.
Many use Scala and Clojure as filter for good developers, but the daily work language is still Java.
It's noticeable that some companies are switching back from Scala to Java e.g. LinkedIn, Yammer and after using it for a while it's not hard to see why. It's awfully complex and obtuse in many parts.
Clojure simply isn't that popular and likely won't be.
(I have no connection with any selling of concurrency solutions; I use scala (including spark and scalaz-stream) professionally)
[1] Why the fuck am I supposed to trust someone who doesn't understand the distinction between "it's" and "its" to tell me that all of Oracle's language designers got a core piece of infrastructure irrecoverably wrong?
Once i tried streams with lambdas to process a large corpus of data (processing many items in a multi-stage manner). While the code was clean and nice, the performance was horrible. A lot of thread waits, etc. Much worse than handling the whole process on my own with thread pools.
Also there are many catches: for instance, when you start your stream with 1 item there will be only max 1 parallel thread to handle the data, and it doesn't matter if you do some fancy data split on some stage of the stream.
Total failure, could not even get one core feed consistently because they where all fighting for resources.
Maybe could work for Non local or in memory data, but I rebuilt it with queues and a thread pool and it was easy way faster.
Also for anything that is pipelined there is ultimately going to be a bottleneck at the weakest point, which could be the spliterator factory.
If you have too many threads waiting, you've got too many threads. I did a significant amount of testing using threads (on a project I can't share) and found that generically, you should have n + 1 threads when you have n processor cores. If your processor I/O bandwidth is limited, you may find better performance with less processors.
If you're creating something like a tick-store (Michael Stonebraker - newest Turing award winner), you'll need to tune the rest of the system to feed the processors data at the maximum rate too. We were using E15K (and another bigger machine I can't remember) and used processor affinity to make sure all but 3 of the processors were dedicated to parallel threads. The thread count was the number of dedicated processors plus one.
Having too many threads leads to context churn ... think about what you're trying to accomplish and design the system appropriately. And of course, some problems need other solutions.
Task Parallel http://sourceforge.net/projects/tymeacse Data Parallel http://sourceforge.net/projects/tymeacdse Task Parallel http://sourceforge.net/projects/tymeacand
The grist of the three articles is 1. This framework doesn’t belong in core Java. 2. This framework should not be the parallel engine that drives all parallel computing (streams etc.) in Java. 3. It is still failing as a parallel engine no matter what the engineers do.
A little history may help. In 2010, I submitted a proof-of-concept to the good professor showing that scatter-gather works just as well as what he was proposing for Java7. Since he ignored the proof completely, I took the parallel engine out of a Task Parallel product I maintain and put in the Data Parallel engine. This product is also open-source. It is not suitable for an API since it is a full feature Data Parallel product. It is not for sale. It is, and has always been, open-source. Data Parallel only works well on copious processors, which is why I never bothered offering it before.
The software examples I submitted with the articles (downloadable) are sufficient to prove my points. These are not full benchmarks since that isn’t necessary for an article; they prove the point – sequential is usually faster than the parallel version, etc.
There are seventeen points in the first two articles. Not one person has ever said, “Hey Ed, that’s not true.” The points are accurate. There is no B.S. in any of the articles. I may not have the eloquent style of a professional author (yes I am a little blunt, what else do you expect from a programmer) but I did the best I could. If you want to throw eggs at them, fine. At least be specific about which point you think is wrong.
Intel has TBB. Microsoft TPL. If Java wants a parallel engine then they should have copied the others. Using an academic centric product that is based on dyadic recursive division is not the way into the parallel future for Java.