4 ms·
> it did just occur to me that a HashSet could be used, which would save a small amount of memory without introducing the performance issue. I was indeed think
by e12e 7y ago
> it did just occur to me that a HashSet could be used, which would save a small amount of memory without introducing the performance issue.
I was indeed thinking of keeping the "occupied" coordinates in a set-like structure. Not sure how a boolean is stored - is it 8 bits, or a single bit? Either way, just storing two (eg) 64 bit coordinates should trivially align (ish)?
The trick would be to quickly be able to go over all occupied cells and their neighbors in order to build "tomorrow's" board. I suppose the new board might serve as a cache/state helper of sorts, but I think the logic would have to be a bit more complicated.
Maybe it's possible to go from a 1d algorithm to a 2d one by making sure there's a list of occupied cells sorted by their place on a Hilbert curve?
My intuition tells me it's simpler to go center out, than row-by-row (if we store only occupied cells, we need to deal with the empty row "above" our first occurrence somehow - it might be easier to "push" out).
I'd probably have to try and sketch this out on paper though :)
At any rate, I just immediately though storing sn extra dead/alive bit seemed a bit redundant and possibly alignment unfriendly if only "really" needed a list/set of occupied cells.
But perhaps the most pragmatic way of changing just the data structure (and more or less keep the algorithm (with the caveat that I haven't actually looked at the code!))- would be to split each generation in two - a list of live and list of dead cells - each accessible via their coordinates in a quick manner.
- brundolf 7y agoYeah, though my goal with this particular project was to strike a balance between performance and readability, not squeeze out the absolute maximum performance. I.e., I didn't bother with any optimizations that entered the territory of "tricks", where they started to make the code less intelligible. For my use-cases (the configurations included in the repo), the current implementation is not limited by speed (and I didn't even turn on compiler optimizations, which in my experience can give a 20x speed improvement).
- e12e 7y agoOh, I don't mind that at all. All these ideas would need to be be benchmarked anyway :) But ever since implementing a naive (backed by 2d array) game of life, I from time to time play with the idea of trying for something much higher performance. I'm not sure if this one scales to 30fps at 4k for example (maybe it surpasses that on modern hw!). That's the kind of target that'd be fun to aim for. Quite possibly using the frame buffer for state is more efficient anyway.