суббота, 20 июня 2009 г.

Страшная структура STRRET

Это перевод The kooky STRRET structure. Автор: Реймонд Чен.

Если вы игрались с пространством имён оболочки (shell namespace), то вы, без сомнения, встречались со структурой STRRET, которая используется IShellFolder.GetDisplayNameOf для возвращения имён элементов оболочки. Как вы можете видеть по документации, STRRET иногда представляет собой строковый буфер ANSI, иногда указатель на Unicode строку, а иногда (и это страннее всего) смещение в pidl. Что же здесь происходит?

Структура STRRET появляется на сцене в эру Windows 95. В это время компьютеры были относительно медленными и имели ограниченный набор памяти (минимальными требованиями для Windows 95 были 4 Мб памяти и процессор 386DX - который работал на "невероятных" 25 МГц). Было намного быстрее выделить память на стеке (одна простая инструкция "sub"), чем выделять её из кучи (что могло занять тысячи инструкций!), поэтому структура STRRET была спроектирована так, чтобы типичные (для Windows 95) сценарии могли бы быть выполнены без выделения памяти из кучи.

Флаг STRRET_OFFSET поднимает эту планку до ещё больших высот. Часто, вы храните имя внутри самого pidl, и копирование его в структуру STRRET займёт, боже, целых 200 тиков (!). Чтобы избежать этого бессмысленного копирования памяти, STRRET_OFFSET позволял вам просто вернуть смещение в pidl, которое вызывающий потом мог использовать для прямой работы со строкой.

Woo-hoo, вы только что сэкономили копирование строки.

Конечно же, когда с течением времени компьютеры стали быстрее и память уже не стала таким сильным ограничением, эти микро-оптимизации стали скорее раздражающими помехами. Экономия 200 тиков на копировании строки едва ли что-то принесёт вам сегодня. На процессоре 1 ГГц, простая программная ошибка страницы (soft page fault) стоит вам миллион циклов; а аппаратная (hard page fault) стоит десятки миллионов.

Вы можете скопировать ОЧЕНЬ много строк за двадцать миллионов циклов.

И даже более того: сценарии, которые были типичными в Windows 95, уже не являются типичными сегодня, так что исходный сценарий, для которого и создавалась эта оптимизация, сегодня уже практически не встречается. Эта оптимизация пережила свой век полезности.

К счастью, вам не нужно думать о структуре STRRET. Есть несколько вспомогательных функций, которые принимают структуру STRRET и переводят её в что-то более простое для управления.

Помешанность структуры STRRET теперь инкапсулирована в этом коде. Ну и слава богу.

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

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

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.