0-based indexing aligns better with how memory actually works, and is therefore more performant, all things being equal.
Assuming `a` is the address of the beginning of the array, the 0-based indexing on the left is equivalent to the memory access on the right (I'm using C syntax here):
a[0] == *(a + 0)
a[1] == *(a + 1)
a[2] == *(a + 2)
...
a[i] == *(a + i)
For 1-based indexing: a[1] == *(a + 1 - 1)
a[2] == *(a + 2 - 1)
a[3] == *(a + 3 - 1)
...
a[i] == *(a + i - 1)
This extra "-1" costs some performance (through it can be optimized-away in some cases).