Здравствуйте, Videoman, Вы писали:
V>Опциональна, но во всех современных С++ библиотеках она используется.
V>P.S. Относительно вопроса скорости примера: похоже, что С# 6.0 компилятор тупо сгенерировал более быстрый код, чем MSVC. Либо действительно числа не помещаются в буфера SSO и ты, по сути, меряешь скорости разных структур в памяти.
В текушем коде примера случайные числа генерируются в диапазоне [0 .. std::numeric_limits<int32_t>::max()]. То есть, максимальная длина строки не должна превышайть 9-ти символов и SSO должна быть эффективна, если только она используется. Я, не мудрствуя лукаво, добавил функцию, которая выводит в конце минимальный и максимальный интервалы между буферами соседних элементов входной последовательности. И вот, выходит, что не используется SSO, строки здорово разбросаны по памяти:
Hash = 41910796
Processing time: 0.83061 sec
[Distribution in memory]: Min Interval: -3218203360, Max Interval: 1680855496
| Полный текст примера |
| #include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <random>
using Int = int32_t;
std::vector<std::wstring> MakeIntSequence(size_t size)
{
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> distrib(0, std::numeric_limits<int32_t>::max());
std::vector<std::wstring> v;
v.reserve(size);
for (size_t i = 0; i < size; ++i)
{
v.push_back(std::to_wstring(distrib(gen)));
}
return v;
}
Int ParseInt(const std::wstring& wstr)
{
Int res{};
for (auto&& d : wstr)
{
if ('0' <= d && d <= '9')
{
res = res * 10 + d - '0';
}
else
{
throw std::out_of_range("'" + std::to_string(d) + "': Symbol is out of range");
}
}
return res;
}
void testDistributionInMemory(const std::vector<std::wstring>& v)
{
if (v.size() >= 2)
{
std::intptr_t minInterval = std::numeric_limits<std::intptr_t>::max();
std::intptr_t maxInterval{};
const wchar_t* prev = v[0].data();
for (size_t i = 1; i < v.size(); ++i)
{
const wchar_t* next = v[i].data();
std::intptr_t nextInterval = next - prev;
if (minInterval > nextInterval)
{
minInterval = nextInterval;
}
if (maxInterval < nextInterval)
{
maxInterval = nextInterval;
}
prev = next;
}
std::cout << "[Distribution in memory]: Min Interval: " << minInterval << ", Max Interval: " << maxInterval << std::endl;
}
}
int main()
try
{
namespace tm = std::chrono;
const auto vals = MakeIntSequence(0x4000000);
const auto t0 = tm::steady_clock::now();
Int hash{};
for (const auto& val : vals)
{
hash ^= ParseInt(val);
}
const tm::duration<double> dt = tm::steady_clock::now() - t0;
std::cout << "Hash = " << std::hex << hash << std::dec << std::endl;
std::cout << "Processing time: " << dt.count() << " sec" << std::endl;
testDistributionInMemory(vals);
}
catch (const std::exception& ex)
{
std::cerr << "[Unhandled Exception]: " << ex.what() << std::endl;
}
|
| |