Работая над пользовательским распределителем для использования с STL, я обнаружил, что есть некоторые сценарии, в которых std :: allocator значительно превосходит любой пользовательский распределитель, который я пробовал на некоторых платформах Linux.
В Windows, используя обаVC ++ 2019 и clang, я не вижу заметных различий в скорости.
Я не могу понять, почему я вижу эти совершенно разные результаты на платформах Linux (я пробовал и Fedora, и Ubuntu.) Я создал этопрограмма, которая демонстрирует то, что я вижу (заимствование SampleAllocator, представленного в отдельном вопросе, указанном в коде.)
#include <vector>
#include <chrono>
#include <iostream>
// SimpleAllocator code from:
// https://stackoverflow.com/questions/22487267/unable-to-use-custom-allocator-with-allocate-shared-make-shared
template <class Tp>
struct SimpleAllocator
{
typedef Tp value_type;
SimpleAllocator() {}
template <class T> SimpleAllocator(const SimpleAllocator<T>& other) {}
Tp* allocate(std::size_t n) { return static_cast<Tp*>(::operator new(n * sizeof(Tp))); }
void deallocate(Tp* p, std::size_t n) { ::operator delete(p); }
};
template <class T, class U>
bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&) { return true; }
template <class T, class U>
bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&) { return false; }
template <typename T> void TimeInsertions(T &vec, const std::string &alloc_name)
{
auto start_time = std::chrono::steady_clock::now();
for (int i = 0 ; i<=100000000; i++)
{
vec.push_back(i);
}
auto end_time = std::chrono::steady_clock::now();
std::cout << "Time using " << alloc_name << ": "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count()
<< "ms" << std::endl;
}
int main()
{
{
std::vector<int, SimpleAllocator<int>> vec;
TimeInsertions(vec, "SampleAllocator");
}
{
std::vector<int> vec;
TimeInsertions(vec, "std::allocator");
}
}
Учитывая этот базовый пример, я ожидал, что ссылочный SimpleAllocator будет работать примерно так же, как std:: allocator, но на самом деле я вижу такие результаты:
$ ./sample
Time using SampleAllocator: 5283ms
Time using std::allococator: 1485ms
Конечно, эти результаты различаются в зависимости от машины, но я получаю одинаково очень разные результаты на разных машинах Linux.Это наводит меня на мысль, что в g ++ или Linux есть какая-то магия, которую я не до конца понимаю.Может ли кто-нибудь помочь мне понять, что я вижу?
РЕДАКТИРОВАТЬ
Возвращаясь к этому сегодня, возможно, это может быть связано с оптимизацией компилятора,Я перекомпилировал код в Linux, используя флаг -O3
в gcc, и получил очень разные (и более близкие) результаты:
$ ./sample
Time using SampleAllocator: 341ms
Time using std::allocator: 479ms
Итак, возможно, это просто связано с тем, как код STL компилируется ине имеет ничего общего с оптимизацией конкретной платформы.