1

for example:

const arr = [1,2,3,4];

const coordinate = [arr[0] + 2, arr[0] + 1];

here arr[0] is written out twice, when the code is executed would it literally go and find same value twice or would it remember it?

Does it matter that arr[0] in example above is used in the same expression? What if I would use arr[0] in the beginning of the file and at the end of the file?

Would it make sense to put arr[0] into a variable for performance?

4
  • 1
    Have you profiled performance and found this bit of code to be problematic?
    – mmathis
    Aug 1, 2022 at 18:16
  • I don't have exact case, example is just for illustration of what I am trying to understand. I just want to know how this things work. Something so common as retrieving a value is gonna be used very often so if there is a difference it could matter on a large scale.
    – link2name
    Aug 1, 2022 at 18:29
  • 1
    Does this answer your question? Is micro-optimisation important when coding? Aug 1, 2022 at 18:34
  • I don't think it does.
    – link2name
    Aug 1, 2022 at 21:37

3 Answers 3

4

It depends.

Some compilers or runtimes (since you tagged this JavaScript) may be able to optimize this, and will sometimes choose to do that. Future versions may choose differently. Hardware may be able to optimize it so that the second retrieval runs faster even if your language runtime is going through the same motions.

But you can't really rely on it. With compilers you can run them and inspect the results to see if it was optimized. With runtime optimizations, you don't even have that option - even if its optimized on your machine, that's no guarantee for the next guy, or even the next run.

If you know that the lookup is expensive (which is unlikely in your simple example), you should cache it yourself. If it's not expensive, save the effort for something that is.

3

You don't even know that it will read the same value. In an asynchronous environment something else could have written to arr[0] between your reads.

while(true) {
  if (arr[0] === null) {
    runNextInstruction();    
  } else {
    handleInterrupts(arr[0]);
  }
}

This code never sets any bits in arr[0]. But if some other code sets some bits it will handle them and clear them. This doesn't work if the language caches previous reads of arr[0]. And that's why most languages don't cache this for you. No amount of analyzing this code will tell you how it should be cached. For that you have to understand the world around the code.

Now some languages, like Rust, will force you to be explicit about things like shared mutable state. Javascript isn't one of them. And even in Rust you never really know if your code is the only thing that knows the address you're looking at. Sometimes what's writing to that address is hardware. Sometimes it's cosmic rays.

When you cache it yourself you are changing the logical behavior of the program. It may give you the same logic 99.9999% of the time. But that's still not 100%. It's up to you whether to care about that.

As for the amount of time, most hardware has a memory hierarchy. Here data gets copied from large slow memory to small fast memory as it gets used. Miss that fast memory with your read and it has to go access slow memory. This goes from CPU registers all the way down to the page file on the hard drive.

Which kind of memory your read will hit changes over time. So no, it doesn't necessarily take the same amount of time. Even if you cache it yourself. You don't have that kind of control in a high level language.

2
  • JavaScript does not support shared-memory concurrency, so this concern is not relevant.
    – JacquesB
    Aug 3, 2022 at 16:38
  • 1
    If someone could change arr[0] between two reads, they could also change it just before the first or just after the second read, so you don't know what the value of coordinate will be - it may be inconsistent with arr[0], it can obviously have a totally different value, and if another thread wrote arr[0] += this; arr[0] += that; then you might calculate coordinate from the totally wrong value. Multithreading is a huge can of worms that you don't fix by changing some order of code.
    – gnasher729
    Aug 4, 2022 at 16:12
0

I might put arr[0] into a variable for clarity, but not for speed. e.g. (guessing at what it might be)

let origin = arr[0];

Unless that code is inside a loop where high performance is needed, there's little point in optimizing for speed.

1
  • 2
    The advantage is when I read your code, I am 99.99% sure you wanted to use the same array element twice. In the original code, there is a much bigger chance that the same index was used twice by mistake. If I saw arr[0] + arr[1] + arr[2] + arr[0] I would. guess that the second zero should be a 3.
    – gnasher729
    Aug 2, 2022 at 7:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.