
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.238.134.157] |
![]() |
|
Страницы: (3) 1 2 [3] все ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#31
,
|
|
![]() ![]() #include <chrono> #include <iostream> #include <thread> #include <utility> /* динамически полиморфная иерархия */ struct DynaPolyBase // интерфейс { virtual void doIt() const = 0; }; // реализации struct DynaPolyDerived1 : DynaPolyBase { virtual void doIt() const {}; }; struct DynaPolyDerived2 : DynaPolyBase { virtual void doIt() const {}; }; struct DynaPolyDerived3 : DynaPolyDerived1 { virtual void doIt() const {}; }; /* статически полиморфная иерархия */ // реализации struct StatPolyDerived1 { void doIt() const {}; }; struct StatPolyDerived2 { void doIt() const {}; }; struct StatPolyDerived3 { void doIt() const {}; }; template <typename Class> requires ( requires { std::declval<Class>().doIt(); } ) // интерфейс struct StatPolyBase : Class { }; /* простой тестер */ template <typename C, auto Count = 1000u * 1000 * 1000> void doIt(const C& c) { for (decltype(Count) i = 0; i < Count; ++i) c.doIt(); } int main() { auto start = std::chrono::high_resolution_clock::now(); StatPolyBase<StatPolyDerived2> item1; DynaPolyDerived2 item2; doIt(item1); // чек статики auto diff = std::chrono::high_resolution_clock::now() - start; std::cout << diff << std::endl; start = std::chrono::high_resolution_clock::now(); doIt(item2); // чек динамики diff = std::chrono::high_resolution_clock::now() - start; std::cout << diff << std::endl; } ![]() ![]() 200ns 610564600ns |
Сообщ.
#32
,
|
|
|
Qraizer, что-то у тя какая-то жуть
![]() Я попробовал твой пример прогнать в https://www.onlinegdb.com, выбрал там стандарт С++20, чет он заругался на твой код в отдельных местах. Ну не суть, я подредактировал. Посмотри, я ничего в логике не поломал? ![]() ![]() #include <chrono> #include <iostream> #include <thread> #include <utility> /* динамически полиморфная иерархия */ struct DynaPolyBase // интерфейс { virtual void doIt() const = 0; }; // реализации struct DynaPolyDerived1 : DynaPolyBase { void doIt() const override {}; }; struct DynaPolyDerived2 : DynaPolyBase { void doIt() const override {}; }; struct DynaPolyDerived3 : DynaPolyDerived1 { void doIt() const override {}; }; /* статически полиморфная иерархия */ // реализации struct StatPolyDerived1 { void doIt() const {}; }; struct StatPolyDerived2 { void doIt() const {}; }; struct StatPolyDerived3 { void doIt() const {}; }; template <typename Class> // интерфейс struct StatPolyBase : Class { }; /* простой тестер */ template <typename C, auto Count = 1000u * 1000 * 1000> void doIt(const C& c) { for (auto i = 0; i < Count; ++i) c.doIt(); } int main() { StatPolyBase<StatPolyDerived2> item1; DynaPolyDerived2 item2; auto start = std::chrono::high_resolution_clock::now(); doIt(item1); // чек статики auto diff = std::chrono::high_resolution_clock::now() - start; std::cout << diff.count() << std::endl; start = std::chrono::high_resolution_clock::now(); doIt(item2); // чек динамики diff = std::chrono::high_resolution_clock::now() - start; std::cout << diff.count() << std::endl; } И вот какие я выводы получил после трех запусков: ![]() ![]() 2908372641 2742338534 ![]() ![]() 1867473111 2083640450 ![]() ![]() 1968410219 2046030004 А в твоем примере вообще какая-то лютая разница ![]() |
![]() |
Сообщ.
#33
,
|
|
Цитата Majestio @ В каких? Концепты не понял? С++20 в полной мере могут не все поддерживать. Та ну и хрен с ними, статика и на утиных работать будет, ей явно объявленные интерфейсы необязательны.Я попробовал твой пример прогнать в https://www.onlinegdb.com, выбрал там стандарт С++20, чет он заругался на твой код в отдельных местах. Ну не суть, я подредактировал. Но ты прав, я сутрировал конечно. Намерено, причём. Включи оптимизацию и познай дзен inline, как говорится. ![]() Твой пример ближе к истине, но тут такое дело... в общем, предсказатель переходов у современных процессоров всё равно не даст нормально потестить разницу в производительности между статически и динамически связанными вызовами. Надо как-то рандомизировать адресаты, чтобы у предсказателя побольше промахов было, иначе даже косвенные вызовы будут связаны статически, но в кэше процессора. И если для динамики это раз плюнуть, то вот для статики... Но это полбеды. Главная беда – это непонятно, а вообще нужно ли этот самый предсказатель нейтрализовывать. Как бы, синтетика синтетикой, но не до такой же степени, когда код сознательно пессимизируется. Добавлено С горем пополам у меня вышло ![]() ![]() 543405900ns 578759500ns Добавлено P.S. Ну не совсем, всё-таки. Код теперь выглядит примерно вот так: ![]() ![]() template <typename C> auto doIt(const C& c) { auto start = std::chrono::high_resolution_clock::now(); c.doIt(); return std::chrono::high_resolution_clock::now() - start; } /* ... */ StatPolyBase<StatPolyDerived1> itemS1; StatPolyBase<StatPolyDerived2> itemS2; StatPolyBase<StatPolyDerived3> itemS3; DynaPolyDerived1 *itemD1 = new DynaPolyDerived1; DynaPolyDerived2 *itemD2 = new DynaPolyDerived2; DynaPolyDerived3 *itemD3 = new DynaPolyDerived3; std::array<DynaPolyBase*, 3> items = { itemD1, itemD2, itemD3 }; std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> distrib(0, 2); decltype(doIt(itemS1)) time = decltype(time)::zero(); // статика for (int i = 0; i < 10000000; ++i) switch (distrib(gen)) { case 0: time += doIt(itemS1); break; case 1: time += doIt(itemS2); break; case 2: time += doIt(itemS3); break; } /* ... */ // динамика for (int i = 0; i < 10000000; ++i) time += doIt(*items[distrib(gen)]); delete itemD1; delete itemD2; delete itemD3; Добавлено Если же подойти к этому ну оооочень аккуратно, то: ![]() ![]() 547698900ns 833802200ns ![]() ![]() 700369200ns 1015749800ns ![]() ![]() 664954600ns 962311400ns Но надо понимать, что если у вас нет аппаратной защиты от всяких там Spectre и вместо стоят программные патчи, то эта синтетика будет показывать попугаев вместо наносекунд. |
Сообщ.
#34
,
|
|
|
Ну да, такое ближе к истине. А то я уже распереживался за динамику, чуть чяем не облился
![]() |