Тема: Швидкість різноманітних операцій ініціалізації вектора і С-масива
Провів тест, ініціалізуючи вектор кількома способами і С-масив. Результати дивні. Наводжу усі необхідні сирцеві коди і результати.
Measure.h
#pragma once
#include <chrono>
template<typename TimeT = std::chrono::milliseconds>
struct Measure
{
template<typename F, typename ...Args>
static typename TimeT::rep execution(F func, Args&&... args)
{
auto start = std::chrono::system_clock::now();
func(std::forward<Args>(args)...);
auto duration = std::chrono::duration_cast< TimeT>
(std::chrono::system_clock::now() - start);
return duration.count();
}
};
PerformanceTest.h
#pragma once
class PerformanceTest
{
private:
int _setsCount = 1000;
int _elemsCount = 1000;
public:
PerformanceTest() = default;
PerformanceTest(int setsCount, int elemsCount) : _setsCount(setsCount), _elemsCount(elemsCount) {}
void Test();
private:
void TestVectorPushBack();
void TestVectorEmplaceBack();
void TestVector();
void TestArray();
};
PerformanceTest.cpp
#include "stdafx.h"
#include "PerformanceTest.h"
#include "Utils\Measure.h"
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
namespace
{
struct TestClass
{
TestClass(int i, int j, int k);
TestClass(const TestClass& other);
int _i;
int _j;
int _k;
};
__declspec(noinline) TestClass::TestClass(int i, int j, int k) : _i(i), _j(j), _k(k) {}
__declspec(noinline) TestClass::TestClass(const TestClass& other) { _i = other._i; _j = other._j; _k = other._k; }
}
void PerformanceTest::Test()
{
cout << Measure<>::execution([](PerformanceTest *c) { c->TestVectorPushBack(); }, this) << endl;
cout << Measure<>::execution([](PerformanceTest *c) { c->TestVectorEmplaceBack(); }, this) << endl;
cout << Measure<>::execution([](PerformanceTest *c) { c->TestVector(); }, this) << endl;
cout << Measure<>::execution([](PerformanceTest *c) { c->TestArray(); }, this) << endl;
}
void PerformanceTest::TestVectorPushBack()
{
for (int i = 0; i < _setsCount; i++)
{
vector<TestClass> v;
v.reserve(_elemsCount);
for (int i = 0; i < _elemsCount; i++)
{
v.push_back(TestClass(1, 2, 3));
}
}
}
void PerformanceTest::TestVectorEmplaceBack()
{
for (int i = 0; i < _setsCount; i++)
{
vector<TestClass> v;
v.reserve(_elemsCount);
for (int i = 0; i < _elemsCount; i++)
{
v.emplace_back(1, 2, 3);
}
}
}
void PerformanceTest::TestVector()
{
for (int i = 0; i < _setsCount; i++)
{
vector<TestClass> v(_elemsCount, TestClass(1, 2, 3));
}
}
void PerformanceTest::TestArray()
{
for (int i = 0; i < _setsCount; i++)
{
void* raw_testClass = operator new[](_elemsCount * sizeof(TestClass));
TestClass *tc = static_cast<TestClass*>(raw_testClass);
for (int i = 0; i < _elemsCount; i++)
{
tc[i] = TestClass(1, 2, 3);
}
operator delete[](raw_testClass);
}
}
PerformanceTest test;
test.Test();
PushBack - 576
EmplaceBack - 672
Vector - 254
C-array - 36
Така жахлива перевага у C-масива. Але те, що emplace гірше ніж push - дуже дивно, адже emplace уникає копіювання. Вектор від С-масива відрізняється лише тим, що вектор копіює наданий йому елемент, а масив постійно створює його. Хтось може пояснити?