Hacker News new | ask | show | jobs
by aba_cz 567 days ago
Regarding Java I'm pretty sure that benchmark is broken at least a little bit and testing something else as not specifying initial size for ArrayList means list of size 10 which gets resized all the time when `add()` is called, leading to big amount of unused objects needing garbage collection.
3 comments

It would indeed be better to create appropriately sized storage.

However, I don't think that underlying array is resized every time `add` is called. I'd expect that resize will happen less than 30 times for 1M adds (capacity grows geometrically with a=10 and r=1.5)

From the docs: "The add operation runs in amortized constant time, that is, adding n elements requires O(n) time".

Given the linear time time complexity, it seems obvious that adding a thread pointer to the list won't contribute substantially to the thread creation time.

The way these kinds of operations can be implemented for amortized linear time (also in Python, C realloc, etc) is explained in https://en.wikipedia.org/wiki/Dynamic_array#Geometric_expans...

Yeah that is a junior mistake... They should've pre-sized the ArrayList, or better, used an array because that's more memory efficient (and I would say would be what any decent dev would do when the size of tasks is known beforehand).

> Some folks pointed out that in Rust (tokio) it can use a loop iterating over the Vec instead of join_all to avoid the resize to the list

Right, but some folks also pointed out you should've used an array in Java in the previous blog post, 2 years ago, and you didn't do that.

And folks also pointed out Elixir shouldn't have used Task in the previous benchmark (folk here being the creator of Elixir himself): https://github.com/pkolaczk/async-runtimes-benchmarks/pull/7

The difference between an arraylist with correct initial size and an array is almost nothing. Arraylist itself is just a wrapper around an array.
It can be a big difference if boxing is involved. Or if the list is very big, because all access to items in the list require casting at the bytecode level (due to type erasure).