суббота, 26 июня 2010 г.

Частое обращение к полям класса может быть невыгодным

Инкапсуляция данных - это, конечно, хорошо. В том смысле, что улучшает структурированность и расширяемость. Однако, прежде чем писать что-то высокопроизводительное, используя ООП, нужно узнать свой компилятор поближе.
Возьмем обычное умножение матриц. Их уже давно никто вручную не умножает, потому что умножение больших матриц нигде не используется, а умножение маленьких матриц - вообще не задача для высокопроизводительных вычислений. Однако именно перемножение больших матриц является своеобразным испытанием для компилятора, так как теоретически сложность алгоритма фиксирована, а на практике зависит от расположения матриц в памяти.
Возьмем простейший пример. Есть класс Child, в нем есть в качестве полей три матрицы и метод, который перемножает первые две и кладет результат в третью. Казалось бы, что тут может быть сложного для компилятора?


С компилятором MSVC2008 время перемножения multiply() примерно в два раза больше, чем outside_multiply. На форуме WDC мне ответили, что обращение к полям класса требует постоянного получения *this, и компилятор не может это оптимизировать. Странно, конечно. Ведь, во-первых, указатель *this постоянный по крайней мере в течение выполнения одного метода, а во-вторых, можно же расположить матрицы в памяти так, чтобы они шли хотя бы друг за другом?
Что интересно, компилятор GCC 3.4 для Windows справляется с этой задачей: время перемножения обоими методами одинаковое. GCC 4.1 дает результат похуже, но все равно не такой, как MSVC. Еще один плюс в копилку GCC. Хоть он и строго (иногда излишне строго) соблюдает Стандарт, его оптимизатор превосходит MSVC.
  • rss
  • Del.icio.us
  • Digg
  • Twitter
  • StumbleUpon
  • Reddit
  • Share this on Technorati
  • Post this to Myspace
  • Share this on Blinklist
  • Submit this to DesignFloat

Комментариев нет:

Отправить комментарий

 
Design by BloggerThemes | This template is brought to you by : allblogtools.com