興味があったので、ちょっとしたベンチマークを行って、int
orなどのプリミティブ型float
とユーザー型の間のパフォーマンス デルタを特定しました。
テンプレート クラスVar
を作成し、いくつかのインライン算術演算子を作成しました。Var
テストは、プリミティブとベクターの両方に対してこのループをループすることで構成されていました。
for (unsigned i = 0; i < 1000; ++i) {
in1[i] = i;
in2[i] = -i;
out[i] = (i % 2) ? in1[i] + in2[i] : in2[i] - in1[i];
}
私は結果に非常に驚いていました.私のVar
クラスはほとんどの場合高速であることがわかりました.intのループは平均してクラスで約5700ナノ秒短縮されました. 3000 回の実行のうち、int は 11 倍速かったのに対し、Var
2989 倍高速でした。と同様の結果が得られますfloat
。ここで、Var
は 2991 回の実行よりも 15100 ナノ秒高速です。
プリミティブ型は高速であるべきではありませんか?
編集: コンパイラはかなり古い mingw 4.4.0 です。ビルド オプションは QtCreator のデフォルトであり、最適化はありません。
qmake call: qmake.exe C:\...\untitled15.pro -r -spec win32-g++ "CONFIG+=release"
OK、完全なソースを投稿、プラットフォームは 64 ビット Win7、4 GB DDR2-800、Core2Duo@3Ghz
#include <QTextStream>
#include <QVector>
#include <QElapsedTimer>
template<typename T>
class Var{
public:
Var() {}
Var(T val) : var(val) {}
inline T operator+(Var& other)
{
return var + other.value();
}
inline T operator-(Var& other)
{
return var - other.value();
}
inline T operator+(T& other)
{
return var + other;
}
inline T operator-(T& other)
{
return var - other;
}
inline void operator=(T& other)
{
var = other;
}
inline T& value()
{
return var;
}
private:
T var;
};
int main()
{
QTextStream cout(stdout);
QElapsedTimer timer;
unsigned count = 1000000;
QVector<double> pin1(count), pin2(count), pout(count);
QVector<Var<double> > vin1(count), vin2(count), vout(count);
unsigned t1, t2, pAcc = 0, vAcc = 0, repeat = 10, pcount = 0, vcount = 0, ecount = 0;
for (int cc = 0; cc < 5; ++cc)
{
for (unsigned c = 0; c < repeat; ++c)
{
timer.restart();
for (unsigned i = 0; i < count; ++i)
{
pin1[i] = i;
pin2[i] = -i;
pout[i] = (i % 2) ? pin1[i] + pin2[i] : pin2[i] - pin1[i];
}
t1 = timer.nsecsElapsed();
cout << t1 << endl;
timer.restart();
for (unsigned i = 0; i < count; ++i)
{
vin1[i] = i;
vin2[i] = -i;
vout[i] = (i % 2) ? vin1[i] + vin2[i] : vin2[i] - vin1[i];
}
t2 = timer.nsecsElapsed();
cout << t2 << endl;;
pAcc += t1;
vAcc += t2;
}
pAcc /= repeat;
vAcc /= repeat;
if (pAcc < vAcc) {
cout << "primitive was faster" << endl;
pcount++;
}
else if (pAcc > vAcc) {
cout << "var was faster" << endl;
vcount++;
}
else {
cout << "amazingly, both are equally fast" << endl;
ecount++;
}
cout << "Average for primitive type is " << pAcc << ", average for Var is " << vAcc << endl;
}
cout << "int was faster " << pcount << " times, var was faster " << vcount << " times, equal " << ecount << " times, " << pcount + vcount + ecount << " times ran total" << endl;
}
比較的、float の場合、Var クラスは float よりも 6 ~ 7% 高速で、int は約 3% です。
また、元の 1000 ではなく 10 000 000 のベクトル長でテストを実行しましたが、結果は依然として一貫しており、クラスを支持しています。