Тестирование скорости работы основных конструкций языка
Первый тест очень даже прост, он заключается в измерении скорости прямого вызова (member call), виртуального вызова (virtual call), вызова статик-метода (данная операция полностью аналогична вызову обыкновенной функции), создания объекта и удаления объекта с виртуальным деструктором (create object), создания/удаления объекта с inline-конструктором и деструктором (create inline object), создание template'ного объекта (create template object). Результаты теста приведены в таблице 1.
Таблица 1. Результаты тестирования скорости работы основных конструкций языка | ||||
VC++ | Intel Compiler | Bulder C++ | MinGW (gcc) | |
virtual call | 140 (9) | 134 (9) | 139 (9) | 183 (12) |
member call | 124 (8) | !34 (9) | 103 (7) | 154 (10) |
static call | 121 (8) | 113 (7) | 109 (7) | 118 (8) |
create object | 606 (424) | 663 (443) | 459 (321) | 619 (433) |
create inline object | 579 (405) | 600 (420) | 343 (240) | 590 (413) |
create temlate object | 580 (405) | 599 (419) | 349 (244) | 579 (405) |
Первая цифра - это полное время, затраченное на тест (в миллисекундах); цифра в скобках - количество тактов на одну команду.
Результаты получились очень даже интересными: первое место занял Borland Builder, а вот gcc на вызове методов, особенно виртуальных, показал существенное отставание. По всей видимости - из-за бурного развития COM'а, где все вызовы виртуальные, разработчикам "родных" компиляторов под Win32 пришлось максимально оптимизировать эти типы вызовов. Другим интересным фактом является то, что хорошо оптимизировать создание объекта с inline-конструктором и деструктором смог, опять-таки, только Builder.
Конечно, у MSVC++ также наблюдается небольшой прирост производительности, но объясняется это тем, что MSVC++ очень хорошо "раскручивает" код и все заглушки просто выбрасывает. То есть в тесте с inline-вызовами MSVC++ определил, что вызываемый метод является пустым, и исключил его вызов. После исключения вызова пустого метода у него остался пустой цикл, который компилятор также выбросил.
Borland же в случае использования inline-конструктора делает inline не только вызов метода "Конструктор", но и выделение памяти под объект. То же самое делает Builder относительно деструктора. Любопытно отметить, что с шаблонами Builder работает точно так же, как с inline-методами, чего совершенно не скажешь о других компиляторах.