dyingkneepad is talking about how the cpu actually works (x86-64 & cache hierarchy). It doesn't really matter what constructs a particular programming language does or doesn't have -- we can reason about performance in terms of what x86-64 instructions the cpu ends up executing.
Suppose we want to compute the sum of n scalars, represented as n 32 bit floats, say, and we're weighing up if we should store these n scalars in a linked list or an array. The "introduction to algorithms" analysis might be that both approaches require O(n) storage and O(n) running time, so they're indistinguishable, up to some constants that get absorbed into the big-oh notation.
The basic big-oh analysis is true as a first cut for some theoretical simplification of a machine, but with our performance hats on, maybe we're interested in the constants being small so our code actually runs fast on a real machine -- we need to understand how a real machine works in a little bit more detail, in particular we need to have some crude mental model of the memory hierarchy.
On real hardware, if we use a linked list to store our data then each node in the list may end up in an unpredictable region of memory. The CPU will need to load these fragmented chunks of memory into L1 cache memory. Depending on the whims of the memory allocator, each time we read a node into cache we may get a single useful scalar value surrounded by a bunch of other junk -- our precious expensive L1 cache may be 90% filled with junk and only contain 10% or less useful data. (this is the big downside of "pointer-walking" AKA "pointer-chasing"). If our calculation is bottlenecked by memory bandwidth, we're wasting 90% of our machine's memory bandwidth to read useless data because we chose to store our data in an unpredictable, fragmented arrangement throughout memory.
In contrast, if we store our data in an array in a contiguous block of memory that we linearly traverse, each time we read a chunk of values into L1 cache, all the neighboring values are ones we're going to need to read next as we compute our sum. So we're filling our precious tiny L1 cache with 100% useful data and 0% junk. Because we load multiple useful data values each time we load a chunk of our array into cache, we reduce the number of times we need to load into cache, and also unblock more useful compute-bound work (adding scalar values) that the cpu can keep busy with before we need to load main memory into cache again.
see also:
CppCon 2014: Mike Acton "Data-Oriented Design and C++" https://www.youtube.com/watch?v=rX0ItVEVjHc
2022: Andrew Kelley - Practical Data-Oriented Design (DOD) https://vimeo.com/649009599