Существуют определенные особенности дизайна, которые настолько важны, что пытаться вписать их в структуру «паттерна проектирования» - это упрощение. В конечном итоге они пересекаются и влияют на множество различных шаблонов, и опытные инженеры ищут возможность использовать их. Один из них - оптимизация для местоположения.

Упаковывает ли это сетевое взаимодействие в небольшое количество объединенных запросов; группировка ввода-вывода для учета свойств вращающихся дисков или очень разной физики чтения и записи блоков из флэш-памяти; настройка способа доступа процессора к памяти для оптимизации использования сложной иерархии памяти; все техники обладают схожими свойствами. Упакуйте данные вместе в набор данных ограниченного размера и оперируйте им с временной и пространственной локальностью. Хотя технологии радикально изменились за последние 5 десятилетий, я мог бы написать такое же руководство, когда начал программировать 40 лет назад.

Ценность оптимизации для местности основана на физической реальности трех измерений и скорости света. В будущем это будет так же верно, как и в прошлом.

Если вы можете гарантировать хорошую локальность, вы также можете упростить свои алгоритмы и структуры данных. Office 2016 поставляется с парой интересных примеров использования локальности.

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

Компонент разработан для использования в широком диапазоне сред и пытается минимизировать допущения и устранить ограничения на поведение хоста, такие как модели потоков или технология рендеринга.

Основной движок отвечает за обход входного набора данных и создание этой геометрии. После того, как геометрия сгенерирована, необходимо поддерживать широкий спектр обработки; рендеринг, хуки доступности, проверка попадания по геометрии для интерактивных функций, таких как эффекты выделения и наведения, или анимация между геометриями. Двигатель спроектирован таким образом, что эта геометрия и алгоритмы, которые работают с ней, имеют большую локальность. Хотя набор входных данных может быть очень большим, движок обеспечивает надежную стратегию отбраковки, чтобы воспользоваться преимуществами ограниченного окна просмотра. Затененные элементы или элементы, которые вырождаются в целевом масштабе (например, одноточечные линейные сегменты), могут быть удалены из сгенерированной геометрии. Этот подход позволяет неограниченному входному набору данных генерировать набор функций, которые гарантированно будут хорошо ограниченными.

При разработке интерактивных приложений место в вашей архитектуре, где неограниченный набор данных может быть преобразован в форму с четкими ограничениями и границами, всегда является ключевым элементом вашего дизайна.

Другие методы, такие как поддержка абстрактного итератора над геометрией, позволяют диаграммам дополнительно уплотнять сгенерированный набор результатов, синтезируя его по требованию (например, кодируя серию блоков для диаграммы рассеивания как одно описание блока и затем кодируя только одну точку окна для каждой точки данных). Движок также пытается выделить геометрию как единый компактный блок памяти. Такой компактный подход означает, что большинство диаграмм легко помещаются в память L1.

Большая часть обработки может быть реализована как простой линейный обход потоковой геометрии. Поскольку сгенерированная геометрия гарантированно будет ограниченной и компактной, хосты, интегрирующиеся с компонентом, могут использовать простые методы, такие как клонирование геометрии для использования нескольких потоков (например, передача в средство визуализации). Команда IVY инвестировала в разработку компонента, чтобы гарантировать, что эти характеристики сохраняются с течением времени по мере добавления функций и определения новых визуализаций (например, построение модульных тестов, которые гарантируют, что использование памяти в пиковом и устойчивом состоянии остается строго ограниченным при изменении размеров набора данных). Это особенно хороший урок; Сохранять целостность дизайна с течением времени на удивление сложно. Модульные тесты и другие проверки обеспечивают инженерную инфраструктуру для поддержания целостности исходных принципов проектирования, а также постоянно помогают новым разработчикам в проекте, что это за ключевые принципы.

Это отличный пример компонента, в котором есть много сложностей в дизайне и проектировании, но который служит основному принципу структурирования, который можно очень просто определить.

Еще один интересный пример из проекта Office 2016 - расширенное использование списков команд Direct2D. Списки команд D2D позволяют выполнять ваш обычный код рендеринга, но вместо рендеринга на экран или какую-либо поверхность с полным разрешением, команды рендеринга фиксируются и сохраняются в компактном буфере, который можно использовать для последующего воспроизведения (в отличие от метафайлов Windows).

Такое компактное представление дает ряд преимуществ в плане гибкости конструкции. Фактический код рендеринга может быть выполнен более быстро и предсказуемо, поскольку ему не нужно проходить по поверхности вывода с возможно высоким разрешением, которое может значительно различаться в разных средах выполнения. Это означает, что код по своей сути работает с лучшей локальностью (взаимодействие с графическим процессором и потенциально асинхронный рендеринг усложняют все последствия, но все же в целом верны). Компактный буфер дешевле кэшировать, поэтому приложение может выполнять спекулятивный предварительный рендеринг областей за пределами прямого окна просмотра с меньшими затратами.

Поскольку эти списки команд не имеют внешних зависимостей, их легко передать другому компоненту для управления (так, например, они могут отображаться с предсказуемыми затратами на производительность при выполнении панорамирования касанием в другом потоке, требующем гарантированно высокой скорости отклика, а не с использованием механизма обратного вызова для неконтролируемый клиентский код). Стоимость масштабируется предсказуемо (или не масштабируется вообще) при использовании в широком диапазоне размеров и разрешений экрана - особенно важно, поскольку поддержка была расширена до разрешений экрана, которые варьируются от 100 до 500 точек на дюйм. Отрисовка выполняется быстрее (и более предсказуемо), потому что код не выполняет сложные алгоритмы отрисовки, зависящие от приложения, которые должны проходить по модели данных, настроенной для манипуляций, специфичных для приложения, а не отрисовки. Таким образом, существует лучшая локальность как при генерации инструкций, так и позже, когда они выполняются, чтобы фактически завершить рендеринг на поверхность.

Такой подход к созданию компактного представления, которое можно использовать с высокой локальностью и производительностью и которое можно аргументировать просто из-за ограниченных зависимостей, обеспечивает большую гибкость проектирования. В обоих этих случаях «локальность» также означает локальность зависимостей, которая является общей характеристикой реализаций, следующих этому шаблону.

Барри Аллин, главный архитектор компонента построения диаграмм IVY, описанного выше, прокомментировал это обсуждение:

Когда я начал свою карьеру в качестве разработчика 16-битных приложений Win3.0 в 1993 году, мы все были вынуждены структурировать данные и код, чтобы они соответствовали 64-килобайтным сегментам данных и кода. Как вы, очевидно, знаете, для этого потребовалось, чтобы структуры данных и шаблоны использования были сильно оптимизированы по размеру, просто чтобы избежать затрат на указатели FAR и HUGE, а также для размещения на гибких дисках ($$). Нас не интересовали и не ценили достоинства местности, все было в том, чтобы оптимизировать размер, чтобы просто пройти через дверь и сэкономить $ для компании. Visio 1.0 начал разработку в 1990 году, а это означало, что их модель данных (DML) и механизм пересчета ShapeSheet (SSE) также должны были соответствовать одним и тем же ограничениям. Это оказалось огромным благословением и главной причиной, по которой Visio может открывать и редактировать массивные чертежи AutoCad, не опрокидываясь. В любом случае, я сравниваю разработчиков, которые писали код Win16, с теми, кто до нас пережил Депрессию. Шрамы заставили постоянно думать о сбережениях, будь то память или деньги. Моя бабушка скончалась перед крахом фондового рынка 2008 года, но я могу гарантировать вам, что она пережила бы это, даже с теми небольшими сбережениями, которые она оставила в свои 90 лет.