*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 [10937 просмотров]