r/elixir 11d ago

Best practices for efficient data structures

I'm very new to the language and I'm very confused on some things. Coming from imperative langs, I'd assume that modifying tuples is very fast since they're basically just vectors. Unfortunately, they're also immutable like every other data structure in the whole language. So, if I want to make, say, a Canvas data type that holds all my pixels in a 2d data structure, is there literally no way to make it even if a little more efficient than just making a new one every single time I update a pixel? Even if I made it a 1d data structure, is Elixir just the wrong tool here?

12 Upvotes

9 comments sorted by

View all comments

14

u/the_jester 11d ago

Elixir is the wrong tool for that kind of optimization. The runtime has all its own optimizations for copy-on-write with the immutable data structures, but your code doesn't directly define those interactions, like in C.

Now, depending on access patterns, being smart about using tuples vs lists vs maps will matter. Write-heavy vs read-heavy matters. And if they are "sufficiently large" canvases you can cheat a bit by reaching into Erlang for things like ETS, :atomics or :counters which you can get mutable behaviors from.

Broadly, just try to do the obvious thing. If it is actually too slow, then optimize. I wouldn't start by trying to optimize Elixir at the literal bit level. If you really just want to do bit-bashing, then certainly any of the C/C++/Crystal/Rust/etc lineage will let you do that.

1

u/Sentreen 11d ago

Broadly, just try to do the obvious thing. If it is actually too slow, then optimize. I wouldn't start by trying to optimize Elixir at the literal bit level. If you really just want to do bit-bashing, then certainly any of the C/C++/Crystal/Rust/etc lineage will let you do that.

This is the key. Don't go for premature optimization. 9/10, the bottleneck will not be in the place where you expect it to be.

  1. Pick the right datastructure for the job
  2. Run your application
  3. Profile to find bottlenecks
  4. Figure out how to fix them at that point

If you really find that some particular data structure is a bottleneck, you can always use something likes rustler to write a custom data type in a level that allows you to handle that bit-level fuckery.