Live data from Hacker News

Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

togototo.wordpress.com

31–40 of 58 posts

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#31
post #2

Cool article! One thing that might be important to people if you're looking at these languages besides just speed: Go and C will tend to have radically lower memory usage (often like 10x) than most of the other languages there, such as Scala. This can be very important depending on what your application is. For me, using Go for game world servers was my choice because I can do so much more simulation per dollar of se…

What's important is the marginal memory usage. I'd rather pay 20-30MB of JVM memory tax upfront it it levels up with C/C++ for long running process and lowers the possibility of a memory leak and memory corruption.

If it was just the 20-30 MB JVM tax, I might be with you. But in applications that allocate and deallocate a lot of memory, the GC of every JVM implementation I've used also hoards memory from the system (well there are a few implementations that give it back, but they cause app performance to nosedive).

If you're building a piece of software that needs to co-exist with other memory intensive processes, the JVM's policy of taking memory and rarely giving it back can cause unnecessary swapping. Heaven forbid you need to run multiple JVMs on the same machine (like with hadoop).

Then you start having to do silly things like specifying how much memory your app is allowed to use which makes me feel like I'm on classic MacOS.

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#32
post #12

Haskell was excluded from this benchmark because I can't figure it out.

Take the code here: https://github.com/logicchains/levgen-benchmarks/blob/master... and run it. Then, take the same code, change the genRooms function to contain: where noFit = genRooms (n-1) (restInts) rsDone tr = Room {rPos=(x,y), rw= w, rh= h} x = rem (U.unsafeHead randInts) levDim y = rem (U.unsafeIndex randInts 1) levDim restInts = U.unsafeDrop 4 randInts w = rem (U.unsafeIndex randInts 2) maxWid + minWid h = re…

I just changed the random number bit, not the 10000000 part, and it took ~100x longer. No idea why.

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#33
post #27

Earlier quoted context omitted.

I noticed that, but you're still allocating for 800 goroutines in the end. I guess in the scope of the benchmark, that is still relatively cheap. It just was a red flag for me.

No worries. A commenter here submitted a faster version, so it uses that now instead anyway.

Thanks :P And now an even faster version for your perusal:

https://github.com/logicchains/Levgen-Parallel-Benchmarks/pu...

> 120 ms improvement over the origin implementation

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#34
post #25

Have sent in a pull request: https://github.com/logicchains/Levgen-Parallel-Benchmarks/pu... Go performance improves from ~470 ms to ~360 ms on my Quad core MBP 15 (Late 2011)

Thanks, that makes it faster than Scala.

Welcome! Now have a look at this: https://github.com/logicchains/Levgen-Parallel-Benchmarks/pu...

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#35
post #23

Why are you parallelizing these in such different ways? For example, in Go you start 800 goroutines, but in others you start just 4 threads/tasks as worker pool. I would imagine indeed these would give quite different results.

It's done differently in Go because someone else wrote it, and I found it to be faster than the version I wrote using a worker pool of 4 tasks. If you look closely you'll see it doesn't actually ever run more than 4 goroutines simultaneously.

The original was running upto 8 goroutines (my runtime.NumCPU() is 8.)

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#36
post #23

Why are you parallelizing these in such different ways? For example, in Go you start 800 goroutines, but in others you start just 4 threads/tasks as worker pool. I would imagine indeed these would give quite different results.

I can't say anything about the other languages, but as far as Go is concerned, I suspect it's to achieve better load balancing. See Dmitri's explanation here:

https://groups.google.com/d/msg/golang-nuts/CZVymHx3LNM/esYk...

(Dmitri is one of the main people currently responsible for the further development of the Go scheduler). If you only have 8 goroutines running at a time with 8 cores, and one stalls, that wastes CPU usage. If you have, say, 80, the scheduler will put another one to work so the CPU is idle less often.

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#37
Although it's nice to see which compiler performs best, I'm really curious as to why one compiler outperforms another for the same language. What's gcc's achilles heel for example? (it seems to consistently do worse for every language it's use for)

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#38
post #23

Why are you parallelizing these in such different ways? For example, in Go you start 800 goroutines, but in others you start just 4 threads/tasks as worker pool. I would imagine indeed these would give quite different results.

I can't say anything about the other languages, but as far as Go is concerned, I suspect it's to achieve better load balancing. See Dmitri's explanation here: https://groups.google.com/d/msg/golang-nuts/CZVymHx3LNM/esYk... (Dmitri is one of the main people currently responsible for the further development of the Go scheduler). If you only have 8 goroutines running at a time with 8 cores, and one stalls, that wastes C…

True, but that would apply only when you are dealing with tasks which are likely to stall. In this particular case, we are doing CPU intensive calculations in tight loops and no I/O. I scaled the number of goroutines from 1 to 8 (total cores in my MBP w/ Hyperthreading), and got best performance with 8. Performance started regressing beyond 8

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#39
Odd. Why is the C version so much slower than the C++ version? The only thing I notice that's odd is the unnecessary Room/Tile structs + memcpy in MakeLevs, but that can't be responsible for that level of difference.

Also there is a small bug in the C version. When it goes to print out the level, it only compares the first 100, so it'll print a different level from the C++ version with a seed of say, 20.

Re: Parallel Roguelike Lev-Gen Benchmarks: Rust, Go, D, Scala and Nimrod

#40
This is not really too relevant to the article, but that random generator makes me cringe. You can replace it with a decent quality one (xorshift) with about as many lines of code:

  uint32_t genrand(uint32_t *seed)
  {
    uint32_t x = *seed;
    x ^= x > 17;
    x ^= x 
Post reply on HN