29 мая 2006

Pessimization is evil

Многие знают, что ранняя оптимизация - корень всех бед. Но и явная пессимизация - тоже большое зло. Зачем писать явно неоптимально, когда можно написать нормально? Правильно, незачем.

Классический пример:
for
(
iterator It(begin()), End(end());
It != End;
++It
)
{
...
}
Здесь:
1. Использование для инициализации копирующего конструктора вместо присваивания. При написании iterator It = begin() компилятор может создать временный объект, хотя может и соптимизировать.

2. Префиксная форма инкремента. Постфиксный инкремент как правило реализуется через префиксный и временную переменную:
iterator operator++(int)
{
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
В таком случае получаем создание временных объектов, которыми мы не пользуемся. Так что лучше сразу написать префиксную форму.

3. Сохранение вычисленного end(). Если написать условие в виде It != end(), то end() может вычисляться при каждой итерации заново. Поэтому лучше его прокэшировать.

Сеегодня нашел еще одну явную пессимизацию, которую я, оказывается, всегда использовал (WinAPI specific):
DC.FillSolidRect(..., WindowColor);
...
DC.SetBkMode(TRANSPARENT);
DC.SetTextColor(TextColor);
DC.DrawText(...);
То есть заполнял фон, затем писал на нем текст, используя "прозрачный" цвет фона при отрисовке текста.

А теперь подумаем о том, что сейчас у большинства пользователей Windows включен тот стандартный или ClearType антиалиасинг шрифтов. При такой отрисовке многие выводимые пиксели надписи должны отрисовываться с учетом их предыдущего цвета. DrawText() не знает, что мы до этого всю область окна зарисовали каким-то одним цветом. И при отрисовке текста в режиме TRANSPARENT будет считывать то, что уже отрисовано, накладывать на него текст... А ведь можно от этих мучений легко избавиться:
DC.FillSolidRect(..., WindowColor);
...
DC.SetBkMode(OPAQUE);
DC.SetBkColor(WindowColor);
DC.SetTextColor(TextColor);
DC.DrawText(...);

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