Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 55, средняя оценка - 4.71
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
#1

Производительность операций - C++

20.11.2011, 06:34. Просмотров 7542. Ответов 135
Метки нет (Все метки)

Не уверен в своих силах для самостоятельной оценки сабжа. Где можно найти информацию о производительности стандартных операций с++ (гуглением не справился, нашел только сравнение реализации на с++, джаве и на нескольких интерпретируемых языках)?
То есть интересует информация плана << : * как 1:15 или <= : == как 25:24... То есть, чрезвычайно интересно знать, какие операции выбирать если есть альтернатива.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.11.2011, 06:34     Производительность операций
Посмотрите здесь:

Производительность - C++
Подскажите, где или что почитать о том, как писать БЫСТРЫЕ программы? (про разработку высоконагруженных программ). Копаюсь в интернете -...

Производительность кода - C++
Интересует сабж как таковой, и конкретно это: std::string STR = &quot;ABC&quot;; if ( strcmp(STR.c_str(), &quot;ABC&quot; ) == 0 ) или std::string STR...

Влияет ли на производительность - C++
Влияет ли на производительность определение(тоесть реализация) функций внутри класса, а также использование вложенных классов?

Производительность DLL - C++
Привет всем, у меня вопрос по производительности подключения DLL-ки по сравнению с чтением из файла. В программе использую небольшую...

Производительность многопоточности - C++
Доброго времени суток. Решил заняться многопоточностью, и натолкнулся на непонимание с производиельность Есть код в 2 потока: ...

копирование строк, производительность - C++
подскажи, как максимально быстро скопировать сроку memcpy или я написал свою функцию size_t i = 0; while (*(szReceiver + i) =...

Вопрос про многопоточность и производительность - C++
Здравствуйте! Подскажите пожалуйста ответы на следующие вопросы: 1) Правда ли,что многопоточность в программе позволяет увеличить...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
21.11.2011, 16:31  [ТС]     Производительность операций #2
Мою тему просмотрело 39 человек и всем нечего было сказать. Я решился сам.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#include<iostream>
#include<vector>
 
int main()
{
    setlocale( LC_ALL, "Russian" );
    std::cout.width(5);
 
    typedef std::vector<double> proportions;
    proportions rezults;
    for (int q = 0; q != 200; ++q) { rezults.push_back(0); }
    unsigned long long iterationCounter = 0;
 
    while ( true || false )
    {
        int a, b, c, i = 0;
        
        //Инициализация и присваивание
        __asm
        {
            rdtsc
            mov a, eax
        }
        double n1;
        n1 = 0x55e100;
        __asm
        {
            rdtsc
            mov b, eax
        }
        double n2 = 0x55e100;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        //Префиксный или постфиксный инткримент
        int e = 0;
        __asm
        {
            rdtsc
            mov a, eax
        }
        e++;
        __asm
        {
            rdtsc
            mov b, eax
        }
        ++e;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        /*Насколько быстрее разименование указателя на double, чем итератора std::vector<double>*/
        std::vector<double> arr(1);
        arr[0] = asin(static_cast<double>(1)) * 2;//pi
        std::vector<double>::iterator it = arr.begin();
        double* val = new double;
        *val = arr[0];
        __asm
        {
            rdtsc
            mov a, eax
        }
        *it;
        __asm
        {
            rdtsc
            mov b, eax
        }
        *val;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        /*Обращение к элементу вектора и массива*/
        __asm
        {
            rdtsc
            mov a, eax
        }
        arr[0];
        __asm
        {
            rdtsc
            mov b, eax
        }
        val[0];
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        //Сложение и умножение целочисленно
        int x = 23, y = 1234;
        __asm
        {
            rdtsc
            mov a, eax
        }
        x *= y;
        __asm
        {
            rdtsc
            mov b, eax
        }
        x += y;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        //Вещественно
        double f = log(static_cast<double>(55e12)), g = sqrt(f);
        __asm
        {
            rdtsc
            mov a, eax
        }
        f *= g;
        __asm
        {
            rdtsc
            mov b, eax
        }
        f += g;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
        
        //Извлечение корня и умножение вещественно
        __asm
        {
            rdtsc
            mov a, eax
        }
        sqrt(f);
        __asm
        {
            rdtsc
            mov b, eax
        }
        f *= g;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
 
        //Разименование или обращение по индексу для массива
        __asm
        {
            rdtsc
            mov a, eax
        }
        val[0];
        __asm
        {
            rdtsc
            mov b, eax
        }
        *val;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        
        //Разименование или обращение по индексу для вектора
        __asm
        {
            rdtsc
            mov a, eax
        }
        arr[0];
        __asm
        {
            rdtsc
            mov b, eax
        }
        *it;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        //Меньше или неравно
        __asm
        {
            rdtsc
            mov a, eax
        }
        x < y;
        __asm
        {
            rdtsc
            mov b, eax
        }
        x != y;
        __asm
        {
            rdtsc
            mov c, eax
        }
        rezults[i] = ( rezults[i] * iterationCounter + static_cast<double>( b - a ) / ( c - b ) ) / ( iterationCounter + 1 );
        ++i;
 
        
        if( !(++iterationCounter % 10000) )
        {
            std::cout << "Усреднение №" << iterationCounter << ":\n";
            std::cout << "Инициализация в " << rezults[0] << " раз быстрее, чем обявление+присвоение.\n";
            std::cout << "Префиксный инткримент в " << rezults[1] << " раз быстрее, чем постфиксный.\n";
            std::cout << "Разименование указателя в " << rezults[2] << " раз быстрее, чем итератора.\n";
            std::cout << "Обращение к элементу массива в " << rezults[3] << " раз быстрее, чем к элементу вектора.\n";
            std::cout << "Целочисленное сложение в " << rezults[4] << " раз быстрее, чем умножение.\n";
            std::cout << "Вещественное сложение в " << rezults[5] << " раз быстрее, чем умножение.\n";
            std::cout << "Умнжение в " << rezults[5] << " раз быстрее, чем извлечение корня.\n";
            std::cout << "Указатель в " << rezults[6] << " раз быстрее, чем индекс.\n";
            std::cout << "Итератор в " << rezults[7] << " раз быстрее, чем индекс.\n";
            std::cout << "Неравно в " << rezults[8] << " раз быстрее, чем меньше.\n";
        }
    }
}
Выдал у меня результаты
Код
Усреднение №2620000:
Инициализация в 1.09377 раз быстрее, чем обявление+присвоение.
Префиксный инткримент в 0.998926 раз быстрее, чем постфиксный.
Разименование указателя в 19.9195 раз быстрее, чем итератора.
Обращение к элементу массива в 8.17944 раз быстрее, чем к элементу вектора.
Целочисленное сложение в 1.02781 раз быстрее, чем умножение.
Вещественное сложение в 2.49602 раз быстрее, чем умножение.
Умнжение в 2.49602 раз быстрее, чем извлечение корня.
Указатель в 1.18523 раз быстрее, чем индекс.
Итератор в 1.04466 раз быстрее, чем индекс.
Неравно в 0.424205 раз быстрее, чем меньше.
в Visual C++ 2010, со стандартными настройками оптимизации (не менял, потому, что не знаю что значат настройки). Прошу прокомментировать объективность моего теста. Только умоляю, с премерами. Т. е. если вы говорите, что я что-либо определил неверно (скажем, отключенная оптимизация критически повлияла на скорость обращения к элементу вектора), укажите точно, что не верно (в случае с вектором, скажите, какой именно параметр оптимизации нужно включить).
Я уверен, что тема интересна не только мне, и буду рад, если кто-то проявит интерес и дополнит мой список сравнений своим.
Очень надеюсь, что найдётся человек, имеющий хорошее понятие об оптимизации в какой-либо среде разработки, и сможет сформулировать правило написания объективного теста сабжа.
Bers
Заблокирован
21.11.2011, 16:39     Производительность операций #3
rdtsc нельзя доверять на многоядерных камнях
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
21.11.2011, 16:42  [ТС]     Производительность операций #4
Во время правки, обнаружил явное свидетельство, что в таком виде результат не верен: если поменять местами порядок выполнения в последнем тесте( x < y; и x != y; ), не изменится ничего. Хотя, это можно объяснить тем, что операции выполняются одинаково долго, сопоставимо с затратами на засечение времени.

Добавлено через 1 минуту
Да, кстати. У меня sony Vaio с intel core i3 по моему. 4 ядра (виртуальное удвоение)

Добавлено через 1 минуту
Цитата Сообщение от Bers Посмотреть сообщение
rdtsc нельзя доверять на многоядерных камнях
Возможно, именно из-за этого у меня при небольшом количестве проходов (менее десяти) результаты сильно другие... Да и вообще, постоянно разные. В идеальном тесте соотношение должно быть постоянным.
Сыроежка
Заблокирован
21.11.2011, 16:43     Производительность операций #5
Не стал разбираться в вашем коде, так как сразу столкнулся с вызывающими вопросы конструкциями.

Например, в С++ (если имеется в виду стандарт 2003, как в 2011 я не знаю) нет такого типа, как long long. Или такая вычурная конструкция, как while ( true || false ). Очевидно, что true || false всегда равно true , поэтому почему бы просто не написать while ( true ), если вы имеете в виду бесконечный цикл.

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

То есть поднятый вами вопрос и то, как вы подощли к его решению, не представляет никакого интереса для профессиональных программистов..
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
21.11.2011, 16:45     Производительность операций #6
А еще советую собрать программу в режиме релиза, врубить -O3 и попробовать еще раз.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
21.11.2011, 16:50  [ТС]     Производительность операций #7
процессор Core i5 2530 МГц в яндексмаркете написано

Добавлено через 3 минуты
Цитата Сообщение от Сыроежка Посмотреть сообщение
не представляет никакого интереса для профессиональных программистов..
Уходи из моего топика в раздел для профессионалов, злой человек. У страуструпа, в его великом толмуде написано, что префиксный лучше. Как вы упомянули, для вас очевидно, что компилятор учтёт, что для встроенного типа в данном контектсе разницы нет, и сгенерирует одинаковый код. Мне же, такие вещи, не дают покоя день и ночь. Я мало читал и не уверен, поведёт ли себя компилятор безупречно в таком контексте.
Сыроежка
Заблокирован
21.11.2011, 16:53     Производительность операций #8
Никаких проблем. Могут все уйти из вашего топика, если мнения других вас не интересуют!
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
21.11.2011, 16:54     Производительность операций #9
Цитата Сообщение от CEBEP Посмотреть сообщение
что префиксный лучше.
Эстетика это все, а не борьба за производительность.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
21.11.2011, 17:00  [ТС]     Производительность операций #10
Цитата Сообщение от ForEveR Посмотреть сообщение
А еще советую собрать программу в режиме релиза, врубить -O3 и попробовать еще раз.
Переключил на релиз, результаты изменились! Что такое -ОЗ, не понял... что это?
Код
Усреднение №2900000:
Инициализация в 1.22925 раз быстрее, чем обявление+присвоение.
Префиксный инткримент в 4.56375 раз быстрее, чем постфиксный.
Разименование указателя в 1.07129 раз быстрее, чем итератора.
Обращение к элементу массива в 2.59468 раз быстрее, чем к элементу вектора.
Целочисленное сложение в 2.56498 раз быстрее, чем умножение.
Вещественное сложение в 2.54113 раз быстрее, чем умножение.
Умнжение в 2.54113 раз быстрее, чем извлечение корня.
Указатель в 2.53189 раз быстрее, чем индекс.
Итератор в 2.50638 раз быстрее, чем индекс.
Неравно в 2.58332 раз быстрее, чем меньше.
Цитата Сообщение от Сыроежка Посмотреть сообщение
компилятор генерирует один и тот же код
Посмотрите, для теста в текущем состоянии, префиксный вид работает быстрее вчетверо!

Добавлено через 2 минуты
Цитата Сообщение от fasked Посмотреть сообщение
а не борьба за производительность
Нет, там подробный коментайрий. префиксный в с++ выполняется до каких-либо других операций. таким образом не нужно заводить копию переменной. А при выполнении постфиксного инкремента/декремента создаётся копия переменной, передаваемая для остальных операций, а значение соответствующее идентификатору к которому применена операция меняется независимо от копии.

Добавлено через 1 минуту
Цитата Сообщение от Сыроежка Посмотреть сообщение
если мнения других вас не интересуют
Просто ваша бескомпромиссность не располагает. Ведь уже сейчас, я продемонстрировал, что ваше утверждение о инкрементах/декрементах не верно в абсолютном смысле.
LosAngeles
Заблокирован
21.11.2011, 17:04     Производительность операций #11
Цитата Сообщение от CEBEP Посмотреть сообщение
Посмотрите, для теста в текущем состоянии, префиксный вид работает быстрее вчетверо!
едва ли это так
Код
int e = 0;
                __asm
                {
                        rdtsc
010A1251  rdtsc  
                        mov a, eax
010A1253  mov         dword ptr [esp+1Ch],eax  
                }
                e++;
                __asm
                {
                        rdtsc
010A1257  rdtsc  
                        mov b, eax
010A1259  mov         dword ptr [esp+18h],eax  
                }
                ++e;
                __asm
                {
                        rdtsc
010A125D  rdtsc  
                        mov c, eax
010A125F  mov         dword ptr [esp+20h],eax  
                }
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
21.11.2011, 17:04     Производительность операций #12
Цитата Сообщение от CEBEP Посмотреть сообщение
Что такое -ОЗ, не понял... что это?
Максимальный уровень оптимизации.
Цитата Сообщение от CEBEP Посмотреть сообщение
Нет, там подробный коментайрий. префиксный в с++ выполняется до каких-либо других операций. таким образом не нужно заводить копию переменной. А при выполнении постфиксного инкремента/декремента создаётся копия переменной, передаваемая для остальных операций, а значение соответствующее идентификатору к которому применена операция меняется независимо от копии.
Современные компиляторы, как уже говорилось выше, будут поумнее многих программистов и в состоянии определить когда надо делать копию, а когда нет. Поэтому - исключительно эстетика.

Не по теме:

И не надо мне объяснять почему префиксный лучше, это лишнее

Сыроежка
Заблокирован
21.11.2011, 17:05     Производительность операций #13
Цитата Сообщение от CEBEP Посмотреть сообщение
Посмотрите, для теста в текущем состоянии, префиксный вид работает быстрее вчетверо!

Добавлено через 2 минуты

Нет, там подробный коментайрий. префиксный в с++ выполняется до каких-либо других операций. таким образом не нужно заводить копию переменной. А при выполнении постфиксного инкремента/декремента создаётся копия переменной, передаваемая для остальных операций, а значение соответствующее идентификатору к которому применена операция меняется независимо от копии.
Я вам уже все написал, только вы из-за своего гонора дилетанта не внимательно читаете, что вам пишут другие!
Повторю еще раз, если с первого раза до вас не доходит. Если результат посинкрементной операции для фундаментального типа не присваивается другой переменной, то компилятор генерирует один и тот же код для прединкремента и постинкремента.

Например, в следующих двух примерах никакой разницы нет

C++
1
2
for ( int i = 0; i < 10; i++ );
for ( int i = 0; i < 10; ++i );
Для этих двух строк компилятор генерирует один и тот же код. Поэтому польза от ваших тестов нулевая. Не проще ли сразу посмотреть, какой окд генерируется компилятором? Тем более, как я уже написал, если речь идет о пользовательсикх типах, то тем более ваши оценки не имеют смыса, так как все зависит от сложности реализации пользовательских типов.

Заранее предвижу вашу реакцию, так как дилетанты всегда агрессивны, поэтому убедительная просьба, перечитать мой ответ по крайнней мере два раза, прежде чем, что-то возражать.
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
21.11.2011, 17:08     Производительность операций #14
Цитата Сообщение от Сыроежка Посмотреть сообщение
Для этих двух строк компилятор генерирует один и тот же код.
А если выражаться точно, то никакого кода для этих двух примеров не генерируется
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.11.2011, 17:12     Производительность операций
Еще ссылки по теме:

Производительность CPU, КЕШ, многопоточность - C++
Доброго времени суток! Суть проблемы - есть курсовой по системному программированию но я не знаю с чего и начать ( Тема:...

Константы, геттеры/сеттеры и производительность - C++
Есть глобальная константа, определяющая размер большого количества массивов. Также есть множество обращений к массивам с использованием...

Вычислить суточную производительность каждого полимера - C++
Вычислить суточную производительность каждого полимера и всей батареи из 12-ти аппаратов, если съем полимера с одного кубометра объема...

Производительность контейнеров stl для игры - C++
Есть игрушка, в которой просчитывается коллайд. В конце концов будет юзаться какая-нибудь система, типа разделения локаций на квадранты, но...

Действительно ли использование шаблонов снижает производительность программы? - C++
Просветите пожалуйста. Шаблоны в программе снижают её производительность или нет? и намного ли они больше занимают память чем обычные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Paporotnik
383 / 227 / 7
Регистрация: 06.07.2011
Сообщений: 512
21.11.2011, 17:12     Производительность операций #15
имеется ввиду, что разница в производительности в большинстве случаев настолько несущественна с современными мощностями и компиляторами, что никакого отношения к серьезной оптимизации оно не имеет и чаще всего интересна из чистого любопытства. и когда пишется код, правильнее выбирать то, что очевидно в данной ситуации и наиболее понятно при чтении кода.

и вообще странное противопоставление сложения и умножения...

не проще сравнить ассемблерные команды операций для оценки производительности?
Yandex
Объявления
21.11.2011, 17:12     Производительность операций
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru