При профилировании моего приложения я понял, что много времени тратится на сравнение строк. Поэтому я написал простой тест, и я был удивлен, что "==" намного медленнее, чем string:: compare и strcmp! вот код, может ли кто-нибудь объяснить, почему это так? или что не так с моим кодом? потому что в соответствии со стандартом '==' это просто перегрузка оператора и просто возвращается! lhs.compare(rhs).
#include <iostream>
#include <vector>
#include <string>
#include <stdint.h>
#include "Timer.h"
#include <random>
#include <time.h>
#include <string.h>
using namespace std;
uint64_t itr = 10000000000;//10 Billion
int len = 100;
int main() {
srand(time(0));
string s1(len,random()%128);
string s2(len,random()%128);
uint64_t a = 0;
Timer t;
t.begin();
for(uint64_t i =0;i<itr;i++){
if(s1 == s2)
a = i;
}
t.end();
cout<<"== took:"<<t.elapsedMillis()<<endl;
t.begin();
for(uint64_t i =0;i<itr;i++){
if(s1.compare(s2)==0)
a = i;
}
t.end();
cout<<".compare took:"<<t.elapsedMillis()<<endl;
t.begin();
for(uint64_t i =0;i<itr;i++){
if(strcmp(s1.c_str(),s2.c_str()))
a = i;
}
t.end();
cout<<"strcmp took:"<<t.elapsedMillis()<<endl;
return a;
}
И вот результат:
== took:5986.74
.compare took:0.000349
strcmp took:0.000778
И мои компилируемые флаги:
CXXFLAGS = -O3 -Wall -fmessage-length = 0 -std = С++ 1y
Я использую gcc 4.9 на Linux-машине x86_64.
Очевидно, что использование -o3 делает некоторые оптимизации, которые, как я полагаю, полностью завершают последние две петли; однако, используя -o2, все же результаты выглядят странно:
за 1 миллиард итераций:
== took:19591
.compare took:8318.01
strcmp took:6480.35
P.S. Таймер - это только класс обертки для измерения затраченного времени; Я абсолютно уверен в этом: D
Код для класса Timer:
#include <chrono>
#ifndef SRC_TIMER_H_
#define SRC_TIMER_H_
class Timer {
std::chrono::steady_clock::time_point start;
std::chrono::steady_clock::time_point stop;
public:
Timer(){
start = std::chrono::steady_clock::now();
stop = std::chrono::steady_clock::now();
}
virtual ~Timer() {}
inline void begin() {
start = std::chrono::steady_clock::now();
}
inline void end() {
stop = std::chrono::steady_clock::now();
}
inline double elapsedMillis() {
auto diff = stop - start;
return std::chrono::duration<double, std::milli> (diff).count();
}
inline double elapsedMicro() {
auto diff = stop - start;
return std::chrono::duration<double, std::micro> (diff).count();
}
inline double elapsedNano() {
auto diff = stop - start;
return std::chrono::duration<double, std::nano> (diff).count();
}
inline double elapsedSec() {
auto diff = stop - start;
return std::chrono::duration<double> (diff).count();
}
};
#endif /* SRC_TIMER_H_ */