После прочтения Effective Modern C ++ я пытаюсь найти лучший способ передачи аргументов для сеттеров в классах C ++;представьте следующий сценарий:
Вы пишете приложение, которое анализирует входной файл (например, в формате CVS), передает его в класс модели и затем передает список экземпляров в драйвер базы данных для массовой вставки.
Мыможет говорить только о самой последней и самой лучшей C ++ 14;Я написал свою попытку представить это одним столбцом:
class Person {
std::wstring _name;
public:
template<typename T>
inline void setName(T&& name) { _name = std::forward<T>(name); }
};
Я также написал следующий фрагмент для проверки производительности:
const auto start = std::chrono::system_clock::now();
std::vector<std::shared_ptr<Person>> vec;
for (auto i = 0; i < 999999; i++)
{
auto p = std::make_shared<Person>();
p->setName(L"John Chester Doe");
vec.emplace_back(p);
}
const auto end = std::chrono::system_clock::now();
std::cout << "Took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << " ms" << std::endl;
В моей системе это занимает ~ 175 мс, скомпилированных с MSVC2017 Releasex64 с / O2, отключен SDL, без проверок безопасности (/ sdl- / GS-).Из любопытства я попробовал то же самое в C #:
class Person
{
public string Name { get; set; }
}
var sw = System.Diagnostics.Stopwatch.StartNew();
var i = 0;
var vec = new System.Collections.Generic.List<Person>();
for (; i < 999999; i++)
{
var p = new Person();
p.Name = "John Chester Doe";
vec.Add(p);
}
sw.Stop();
System.Console.WriteLine("Took {0}ms", sw.ElapsedMilliseconds);
И это дает 77мс в режиме выпуска!Естественно, мой вопрос в том, что я делаю не так?Почему мой код на C ++ медленнее, чем код на C # для такой же операции?
Я пытался использовать struct в C ++ (без разницы), передавая значение с помощью const ref (медленнее), передавая значение с помощью std :: move (медленнее)).Я также попытался использовать noexcept (без большой разницы) даже std :: string (без большой разницы).
Спасибо!
Редактировать
Спасибо всем за предложения, очень ценю это.Похоже, что лучший способ достичь того, чего я хочу достичь, это что-то вроде:
std::vector<Person> vec;
vec.reserve(999999);
for (auto i = 0; i < 999999; i++)
{
vec.emplace_back();
vec.back().setName(L"John Chester Doe");
}
Это 75 мс с предварительным распределением, без vec.reserve это 130 мс.