4 ms·
That's not the same. You are just creating a bunch of completed futures. Your code basically is just summing numbers up in a recursion here. Which is not what O
by yankoff 11y ago
That's not the same. You are just creating a bunch of completed futures. Your code basically is just summing numbers up in a recursion here. Which is not what OP is trying to benchmark.
- merb 11y agoactually Future.sequence() will run dispatched. it would just make no sense to run the single number concurrently, as the go version won't do this, too. Future.sequence uses the global Executer. sum := 0 for i := 0; i < div; i++ { sub_num := num + i * (size / div) go skynet(rc, sub_num, size / div, div) } This is the go version and only the inside will run on a thread so I made a fair comparsion P.S: The go version will actually run single threaded when you are having GOMAXPROCS=1.
- yankoff 11y agoGo example seems off too from what the author intentions were. As for the dispatcher, I don't believe it will actually give any resource to a future that is already complete? OP wanted to have messages going through 1M actors, so there would be a moment when each actor gets a thread from a thread pool.
- merb 11y agoHowever it makes a difference if I create 1M actors and dispatch them via reflection or if I create some of them and passing results back and forth. actually goroutines would use static dispatching and don't have a lot of overhead. however a scala actor is totally different than any goroutines or erlang actors, they are keeping a lot of state. a promise/future is actually a little bit better in this kind of sense, still the jvm version will actually (even when optimized) use way more memory.
- sirclueless 11y agoThis is a silly argument. If I read you right, you are saying that a goroutine is closer to a promise/future than a Scala actor in terms of resources used, and therefore it's OK to use futures instead of actors in the Scala code and compare them that way. That betrays the whole benchmark. The basic point of the benchmark is to answer the question, "How expensive is it to create and run 1,111,111 actors in various languages?" You can't make a manual optimization that causes only 111,111 actors to be created and then say that it's a better comparison.
- merb 11y agogoroutine is not an actor. its a concurrency mechanism. so a goroutine is not an actor, however a future (http://doc.akka.io/docs/akka/2.4.1/scala/futures.html#Use_Directly http://doc.akka.io/docs/akka/2.4.1/scala/futures.html#Use_Di...) is definitly closer to an actor than a goroutine. so you can't compare golang and scala/erlang. too bad, huh? And when you are clever you would be comparing monads, which actually a goroutine could be. and a future/promise, too. Btw. Even a Future does more than a goroutine do. it won't crash your whole program when it fails, which a goroutine does.
- sirclueless 11y agoYes, goroutines are a concurrency mechanism. Actors are also a concurrency mechanism, so I fail to see why the comparison is unfair. As you say, Actors are safer in that uncaught exceptions in an actor will not bring down a program. They have a few more dials and knobs, you can store references to them, and they are more heavyweight. They have more overhead as can be expected from these facts and this is exhibited in benchmarks like this one. Futures are not a concurrency mechanism precisely. They are a monadic data structure around possibly-concurrent execution. You can wrap a Future around concurrent execution by an Actor, or you can do what you have done and wrap a Future around a sequential recursive computation. As with the synchronous .NET core implementation of the benchmark, the performance is better due to not having the overhead of Actors or other concurrency. Like the synchronous .NET core implementation writing the computation this way is not a fair comparison to the other languages in the benchmark and the high performance does not indicate anything about the efficiency of the concurrency mechanisms available in Scala.
- sirclueless 11y agoThe goroutine is actually in a separate concurrently executing computation. The "go skynet()" call from the Go example is a real concurrent call that will block on the "c <- xyz" lines and resume execution when a reader consumes the value. Calling Future.successful is not the same thing.
- merb 11y agothe compiler will definitly inline this part: if size == 1 { c <- num return }
- sirclueless 11y agoNo it will not, and can not. "c <- num" is a blocking statement. Since c is an unbuffered channel, execution cannot proceed past the statement until a reader consumes a value. The reader in this case creates 10 goroutines executing "c <- num" and only then starts consuming values. If the statements you wrote were inlined execution would immediately halt in a deadlock.