Если ваша цель - показать, что последовательный доступ быстрее, чем непоследовательный доступ, просто указатель, преследующий последний, не является хорошим способом продемонстрировать это. Вы бы сравнивали доступ через один указатель плюс простое смещение против сдерживания одного или нескольких указателей перед смещением.
Чтобы использовать отслеживание указателя, вы должны применить его к обоим случаям. Вот пример:
int arr[n], i;
int *unshuffled[n];
int *shuffled[n];
for(i = 0; i < n; i++) {
unshuffled[i] = arr + i;
}
/* I'll let you figure out how to randomize your indices */
shuffle(unshuffled, shuffled)
/* Do toning on these two loops */
for(i = 0; i < n; i++) {
do_stuff(*unshuffled[i]);
}
for(i = 0; i < n; i++) {
do_stuff(*shuffled[i]);
}
Если вы хотите лучше рассчитать время прямого доступа, вы можете создать простую формулу для продвижения индекса вместо полной рандомизации доступа:
for(i = 0; i < n; i++) {
do_stuff(arr[i]);
}
for(i = 0; i < n; i++) {
do_stuff(arr[i / 2 + (i % 2) * (n / 2)]);
}
Это будет работать правильно даже для n
, как показано, но это иллюстрирует идею. Вы можете пойти так далеко, чтобы компенсировать дополнительные провалы в вычислении индекса в пределах do_stuff
.
Вероятно, самым большим тестом между яблоками и яблоками будет буквальный доступ к нужным индексам без циклов или дополнительных вычислений:
do_stuff(arr[0]);
do_stuff(arr[1]);
do_stuff(arr[2]);
...
do_stuff(arr[123]);
do_stuff(arr[17]);
do_stuff(arr[566]);
...
Поскольку я предполагаю, что вы захотите тестировать с большими массивами, вы можете написать программу, которая сгенерирует для вас реальный тестовый код и, возможно, скомпилирует и запустит результат.