How much temporary data can be stored with Tuples?


#21

That changes everything I originally thought about Tuples / “stack allocation”. Wow…

edit: Thanks for putting up with me, I think I’m understanding it better and better
edit2: I have an idea for another test script. Going to fiddle around with this today


#22

You are very welcome.


#23

Also another clarification that I think @stronny mentioned but I want to go deeper: when a program is compiled, the compiler (in this case LLVM) will know how much stack space every function needs. So if in your method you have:

def foo
  a = {1, 2, 3}
  a
end

then it can see that you need 12 bytes (4 bytes per int, 3 ints = 12), and that’s it.

Variables are easy to see, but the compiler will allocate memory for function calls too, basically temporary unnamed data. For example:

def foo
  loop do
    call_something(make_tuple)
  end
end

Let’s say make_tuple returns the same tuple as above, 12 bytes. Then the compiler (or the LLVM that we generate) looks something like this:

def foo
  space_for_tuple = ...
  loop do
    space_for_tuple = make_tuple
    call_something(space_for_tuple)
  end
end

so even if you make millions of tuples, they are always stored in the same place in the stack… because each loop iteration doesn’t need to know the previous values. And if you do need them, well, you are passing them (by copying them) to call_something.

When you do:

hash[key] = tuple

that is actually a method call:

hash.[]=(key, tuple)

so a copy of the tuple is passed to the method. Eventually somewhere in Hash’s code the hash has a pointer to heap memory and that’s where the tuple’s contents are stored. If it’s something other than a hash, let’s say a struct, and that struct is a local variable, then the tuple’s contents are copied to that’s struct’s space, and because it’s a local variable and it lives in the stack then it’s copied there.