БлогNot. *s++ или *(s+i)

*s++ или *(s+i)

Разрешение ещё одного небольшого спора, касающегося C++. Коллега утверждал, что сканирование строки вида *s++ предпочтительнее, чем *(s+i) с последующим увеличением i - типа, многократное вычисление *(s+i) будет тратить время. Я говорил, что s+1 и s+i едва ли заметно отличаются по скорости и вряд ли в каком-то компиляторе коды дадут несомненную разницу во времени исполнения. Проверим, так ли это, в консольном C++ с отключенной оптимизацией кода.

В приведённой ниже программке небольшая строчка копируется 10 миллионов (1e7) раз с помощью двух различных функций копирования. Обе функции возвращают указатель на скопированное, как и положено методу strcpy.

Заодно пример показывает достаточно кроссплатформенный способ получения на C++ времени выполнения кода в миллисекундах (точней, в секундах и некоторых долях секунды, предельная точность зависит от платформы и процессора) с помощью одной функции и одной константы стандартной библиотеки time.h.

Вариант 1, запоминаем указатель на начало строки и сдвигаем оригинальный указатель.

#include <stdio.h>
#include <time.h>

char *strcpy (char *d,char *s) {
 char *d0=d;
 while (*d++=*s++);
 return d0;
}
void main () {
 char *buf="          ";
 clock_t start,end; double elapsed;
 start=clock();
 for (long int i=0; i<1e7; i++) strcpy (buf,"Hello,win");
 end=clock();
 elapsed=((double)(end-start)/CLK_TCK); //CLOCK_PER_SEC в ряде реализаций
 printf ("\nresult=%lf",elapsed);
}

Вариант 2, каждый раз вычисляем смещение до нужного байта в теле цикла, а указатель не трогаем.

#include <stdio.h>
#include <time.h>

char *strcpy (char *d,char *s) {
 int i=0;
 while (*(d+i++)=*(s+i));
 return d;
}
void main () {
 char *buf="          ";
 clock_t start,end; double elapsed;
 start=clock();
 for (long int i=0; i<1e7; i++) strcpy (buf,"Hello,win");
 end=clock();
 elapsed=((double)(end-start)/CLK_TCK); //CLOCK_PER_SEC в ряде реализаций
 printf ("\nresult=%lf",elapsed);
}

Таблица сравнения времени нескольких прогонов обеих программ.

Вариант 1: *d++=*s++	Вариант 2: *(d+i++)=*(s+i)
6.648352		6.593407
6.648352		6.648352
3.736264		3.571429
6.318681		6.538462
6.593407		6.593407
6.703297		6.538462
6.593407		6.428571

Как видим, второй вариант в моей консольке даже срабатывал и побыстрее, хотя статистически значимой разницы действительно нет.

10.04.2013, 15:08 [10770 просмотров]


теги: c++ программирование время

К этой статье пока нет комментариев, Ваш будет первым