...

суббота, 9 июля 2016 г.

Целесообразность и преимущества применения серверных накопителей, построение RAID-массивов, стоит ли экономить и когда?

На рынке доступно большое количество накопителей различных скоростей, различных производителей. Далеко не все четко понимают, какой диск лучше приобрести и для какой задачи и зачем порой лучше заплатить больше, а когда можно сэкономить. В этой статье я постараюсь прояснить основные моменты и сделать проблему выбора более простой. Статья будет полезна не только тем, кто хочет купить/арендовать выделенный сервер, но и тем, кто хочет получить надежное хранилище информации дома. После прочтения материала станет понятным, почему не всегда целесообразно арендовать desktop-решения в low-cost дата-центрах и лучше остановить выбор на более надежном, серверном железе.

Начнем с того, что все имеющиеся на рынке накопители, можно четко разделить на классы:

— диски для обычных desktop-ов (применяются в домашних ПК, в ноутбуках и в desktop-серверах low-cost дата-центров);
— серверные диски со скоростью 7200 оборотов в минуту (RPM);
— Enterprise-диски со скорость 10 000 и 15 000 RPM;
— твердотельные накопители.

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

Начнем с обычных дисков для PC. Это отличные диски с довольно большой емкостью и хорошей производительностью, но их главный недостаток в том, что они не рассчитаны на работу в RAID-массиве в силу своих конструктивных особенностей. В этих дисках вибрации, вызываемые вращением шпинделя, практически никак не компенсируются. Конечно эти вибрации минимальны и в случае применения 1-2 дисков в домашних условиях они не являются проблемой. Однако, если рассматривать серверный случай, когда дисков много, влияние вибраций может быть довольно существенным, так как возникают взаимные вибрации, резонанс усиливает эффект. Так, когда в корпусе установлено сразу 12 дисков, да еще и работают довольно мощные серверные вентиляторы по 5000-9000 оборотов в минуту — уровень вибрации нарастает довольно значительно, а с ними и % ошибок, потерь, что и оказывает негативное влияние на производительность. Производительность дисков десктопного типа падает в этих случаях в разы, так как они испытывают значительные трудности с позиционированием головок, теряют дорожку. Это хорошо можно видеть из популярного графика зависимости производительности от вибрационной нагрузки:

Другое дело диски SATA RE (RAID Edition) или же серверные диски со скоростью 7200 RPM. Они менее подвержены вибрациям и в меньшей степени зависят от них. Как видим из графика — вероятность возникновения ошибки в результате вибраций на 50% ниже для них.

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

Для SATA PC дисков уровень невозобновимых ошибок 1 ошибка на 1014 бит, или 1 ошибка на 12,5 ТБ данных. Диск на 1ТБ имеет 1000/12500х1014 бит. 5 дисков имеют емкость 5х(1000/12500х1014) бит, а вероятность возникновения ошибки при работе этих дисков в массиве RAID5 будет составлять (5х(1000/12500х1014))/1014x100% = 40%.

Как видим, использовать 5 PC-дисков в RAID5 просто нельзя, так как вероятность возникновения невосстановимой ошибки при ребилде очень высока и ребилд завершится скорее неудачно. Таким образом мы получим массив, который заведомо выйдет из строя в случае ребилда и данные будут утеряны. Ранее я не знал об этой особенности и в 2008-м году, когда собирал свой первый сервер еще на PC-шных накопителях, построил именно RAID5-массив, с целью экономии дискового пространства и денег, и менее, чем через месяц, данные были потеряны. Сейчас мне удивительно, что массив прожил так долго :)

Конечно, можно применять более надежные уровни RAID, такие, как RAID10 или в крайнем случае RAID6, но при большом количестве дисков мы также будем получать довольно высокую степень вероятности возникновения невосстановимой ошибки во время ребилда.

Другое дело серверные диски со скоростью 7200 оборотов в минуту (RPM) SATA RE или диски Near Line (NL) SAS. Вероятность невосстановимой ошибки для них на порядок меньше уже за счет их технических особенностей, 1 ошибка возникает на 1015 бит данных. Тем не менее, при использовании не только большого количества накопителей, но и накопителей большого объема — этого может быть уже недостаточным и в таких случаях все же придется применять SAS-накопители Enterprise класса, степень надежности которых 1 невосстановимая ошибка на 1016 бит данных.

Стоит также отметить, что на самом деле для дисков SATA RE, Near Line (NL) SAS и дисков SAS Enterprise-класса, по сути дисков, которые умеют эффективно взаимодействовать с RAID-контроллером, вероятность возникновения невосстановимой ошибки еще значительно меньше, как раз за счет этой способности. Так, при работе с нагруженным массивом (базы данных, с которыми работают сразу много пользователей, активная запись и считывание данных) начинают играть роль уже восстановимые ошибки, с которыми обычные диски работают неэффективно. Они пытаются перечитать проблему многократно — в тех же Western Digital значение установлено на 64 прохода головки с разными параметрами высоты, угла, только после чего головка переходит к обработке других задач. За счет этого сильно возрастает время ожидания, которое RAID не терпит и непременно сочтет диск потерянным и попытается восстанавливать диск, в результате чего нагрузка на массив приобретет критичный характер, так как одновременно с рабочей нагрузкой будет идти еще и ребилд. Результат предсказуем — крах всего массива.

Диски, которые умеют работать с RAID, могут сообщить RAID-контроллеру, что есть проблема с чтением блока данных, запросить этот блок с других дисков и в это время обрабатывать другие запросы, а получив блок — перезаписать его в другом месте проблемного диска. За счет этого никакого падения производительности RAID-массива не происходит и вероятность потери данных снижается значительно. Однако следует отметить, что не все софтовые рейд-контроллеры, установленные на чипсетах, умеют «понимать» такие диски, потому порой недостаточно иметь диски RE для надежного массива, а все же требуется применение аппаратного контроллера или другой платформы, которая корректно работает с RAID.

Тем не мене, если есть желание собрать более надежное хранилище, нежели хранилище на PC-накопителях, можно купить более дешевые диски, нежели диски RE, к примеру Constellation CS, которые предназначены для работы исключительно с софтовыми рейдами и лишены недостатка десктопных (попыток многократного перечитывания данных в ущерб другим задачам), при этом полноценно, само собой, с контроллерами они не взаимодействуют, так что cбои RAID полностью не исключены.

Вне зависимости от того, какой накопитель Вы применяете, Вы также должны помнить о том, что у дисков есть кеш — 32, 64 МБ и более. Что это значит для RAID-массива? С точки зрения производительности кеш является плюсом, как для чтения, так и для записи. Однако с точки зрения надежности записи — это минус. Используя кеш, рейд-контроллер будет думать, что уже записал данные на массив, но на самом деле они могут быть только в кеше, а на диск записаны быть позднее. В зависимости от размера массива растет и размер общего кеша, и в случае 12 накопителей кеш составляет уже почти гигабайт. Что произойдет с данными при отключении питания? Правильно. Они будут утеряны. И если речь идет о файлопомойке, тут, наверное, не на столько критично, но если же речь идет о базах данных — будет весело. Потому рекомендуется для данных особой критичности, такие, как базы данных, все же отключать кеш на запись. Это снизит производительность диска на 8-15% в режиме баз данных, однако в значительной степени увеличит надежность. По этой причине, если Вы приобретаете хранилище данных большой емкости, крупные производители отключают там кеш по умолчанию и включить его невозможно. Применяя же диски в серверах, особенно в low-сost дата-центре, где питание к серверу не резервировано, нужно помнить об этом риске и учитывать его.

Также отметим еще одну ключевую особенность дисков SAS Enterprise-класса, на них данные хранятся еще более надежно, так как минимальный размер кластера составляет 520 байт, а не 512, добавляется еще 8 байт для проверки четности. Применяется большое количество алгоритмов восстановления данных без участия контроллера. Именно по этой причине объем этих дисков не бывает очень большой.

К слову на счет объема, крайняя рекомендация, если у Вас есть задача хранить данные надежно, не пытайтесь использовать диски большего объема, нежели это необходимо, так как в случае ребилда восстановление будет занимать больше времени. Как правило контроллеры не анализируют то, сколько реально занято на диске и восстанавливают весь диск в целом, потому разница во времени восстановления между 1 ТБ и 6 ТБ накопителем будет более, чем в 6 раз.

Подведем итоги. Исходя из вышеизложенного понятно, что для небольшого RAID-массива, применение самых дорогостоящих дисков Enterprise класса не принципиально и не дает никаких преимуществ в надежности. Тем не менее, применение серверных дисков весьма желательно, так как в этом варианте на порядок большая вероятность того, что ребилд завершится успешно. Не следует применять диски большего объема, чем это необходимо, за исключением случаев, когда нужно обеспечить более высокую производительность по IOPS (в некоторых дисках большего объема все же может быть выигрыш по скорости за счет большего количества головок и пластин). В случаях, когда необходим большой объем и много дисков и при этом достаточный уровень надежности — можно смотреть в сторону SAS NL, которые по сути являются модифицированным вариантом накопителей SATA RE за счет интерфейса SAS, однако имеют все те же 7200 RPM. Для повышения уровня надежности целесообразно применять RAID более высокого уровня. Когда же объем массива не принципиален и требуется максимальная надежность, нужно однозначно применять SAS 15000 RPM Enterprise.

Теперь, выбирая в аренду сервер в Нидерландах, у нас на площадке Switch, при помощи конфигуратора, расположенного в нижней части страницы http://ift.tt/1wZGwiJ, либо, модифицируя одно из спец. предложений:



Приходит понимание того, какие диски и какой из серверов лучше использовать и для каких задач, когда лучше использовать диски в RAID, а когда по отдельности, распределяя файлы софтом в зависимости от популярности (скрипт балансера в зависимости от нагрузки). Почему 4 диска большего объема, в плане надежности, может быть лучше, чем 12 меньшего, но хуже в плане времени восстановления в случае ребилда. Ну и самое важное — почему наше предложение реально крутое для серверного сегмента и мы реально приблизили цену к desktop-площадкам, при этом сохранив на порядок более высокую надежность без преувеличений! Так что если Вам, либо Вашим знакомым нужен хороший сервер — welcome, распродажа некоторых конфигураций из списка ниже ограничена, очень скоро цены на эти конфигурации будут выше, мы хоть и щедры, но не безгранично :):




Да, если у кого-то есть реальный опыт применения тех или других накопителей для определенных задач — не стесняйтесь делиться им в комментариях. Интересно все, вплоть до статистики отказов. На эту тему, как и по поводу проблематики выбора SSD-накопителя, мы постараемся опубликовать материал позднее.

Комментарии (0)

    Let's block ads! (Why?)

    Мессенджер Facebook получит функцию end-to-end шифрования

    [Перевод] Обзор физики в играх Sonic. Части 5 и 6: потеря колец и нахождение под водой

    Продолжение цикла статей о физике в играх про Соника. Часть первая, часть вторая, части третья и четвёртая.

    Часть 5: потеря колец



    Ограничения по кольцам

    Когда Соник ударяется о противника или опасные препятствия, он теряет все кольца, которые собрал, но в разные стороны разлетаются 32 кольца. Так что Соник не может повторно собрать более 32 колец, даже если их у него было 100.

    Разлёт колец

    Кольца, разлетающиеся от Соника, двигаются по определённой траектории из двух концентрических кругов, каждый из которых содержит не более 16 колец. Кольца в первом круге разлетаются быстрее, чем кольца во втором. Вот формула для создания колец, которую можно преобразовать в любой язык программирования:

    {
     let t = 0
     let angle = 101.25 ; где 0=справа, 90=сверху, 180=слева, 270=внизу
     let n = false
     let speed = 4
     
     while t < количества колец
       {
       создать объект "скачущее кольцо"
       установить вертикальную скорость кольца равной -sin(angle)*speed
       установить горизонтальную скорость кольца равной cos(angle)*speed
       if n = true
         {
         умножить горизонтальную скорость кольца на -1
         увеличить угол на 22.5
         }
       let n = not n ; if n = false, n становится true, и наоборот
       увеличить t на 1
       if t = 16
         {
         let speed = 2 ; теперь мы на втором круге, так что уменьшаем скорость
         let angle = 101.25 ; снова задаём угол
         }
       }
     }
    
    

    Итак, первые 16 колец двигаются со скоростью 4 пикселя за цикл, а вторые 16 — в два раза медленнее (2 пикселя за цикл).

    Гравитация для колец

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

    Отскакивание колец

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

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

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

    Если бы я использовал систему, мощнее чем Genesis/Mega Drive, я бы запрограммировал кольца проверять горизонтальные столкновения. При столкновении они должны умножать свою горизонтальную скорость на коэффициент -0.25. Также они должны проверять столкновения с потолками, определяя, случилось ли столкновение при движении вверх или вниз. Если они двигались вниз, они должны отскакивать, как обычно, но если они двигались вверх, они должны обнулять свою вертикальную скорость. Это было бы милосерднее к игроку, так большинство колец бы не терялось при попытке повторного сбора.

    Время «жизни» колец

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

    Повторный сбор колец

    После удара Сонику нужно 64 циклов, прежде чем он сможет повторно собрать разлетевшиеся кольца.

    Неуязвимость

    После удара Соник становится на краткий промежуток времени неуязвимым. Эта неуязвимость длится, пока Соник отлетает от удара, а затем ещё 120 циклов после возобновления движения. В течение этих 120 циклов он мерцает, исчезая и появляясь через каждые 4 цикла.

    Анимации колец

    Висящие на месте кольца имеют 4 кадра анимации, и сменяют кадры через каждые 8 циклов. Поведение разлетающихся колец более сложно, потому что у них более высокая скорость анимации при создании, но с течением времени она снижается. В начале кадры анимации сменяются каждые 2 цикла, но в конце замедляются и меняются каждые 16 циклов или около того. Пока я не знаю точных значений. Разлетающиеся кольца создаются с одним начальным кадром анимации — кольцо видно целиком.

    Глубина прорисовки колец

    И разлетающиеся, и висящие кольца имеют бОльшую глубину, чем Соник, то есть прорисовываются за ним. Но они имеют меньшую глубину, то есть прорисовываются над ним, когда превращаются в искры.

    Часть 6: нахождение под водой


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

    Ускорение

    Ускорение имеет половинное значение от обычного: 0.0234375.

    Замедление

    Замедление имеет половинное значение от обычного: 0.25.

    Замедление при вращении остаётся неизменным.

    Сила трения

    Сила трения имеет половинное значение от обычного: 0.0234375.

    Сила трения при вращении имеет значение 0.01171875.

    Максимальная скорость

    Максимальная скорость бега Соника равна 3, половине от обычного значения.

    Ускорение в воздухе

    Ускорение в воздухе действует обычным способом, но имеет значение 0.046875, в два раза меньше обычного.

    Гравитация

    Гравитация равна 0.0625. Благодаря этому Соник падает гораздо более медленно.

    Скорость прыжка

    Начальная скорость прыжка равна -3.5 (-3 для Наклза), скорость в момент отделения от земли равна -2.

    Пузыри

    Когда Соник сталкивается под водой с пузырём, его скорости по X и Y обе становятся равны 0.

    Вход и выход

    Когда Соник падает в воду, его горизонтальная скорость умножается на 0.5, а вертикальная скорость умножается на 0.25 (это происходит после добавления гравитации). И наоборот, когда Соник выпрыгивает из воды, его вертикальная скорость удваивается (после добавления значения «водной» гравитации) и он начинает двигаться быстрее, потому что вода больше не влияет на его движение (однако выход из воды не влияет на горизонтальную скорость).

    Утопание

    Когда Соник тонет, его скорости по X и Y обе становятся равными 0, а «водная» гравитация остаётся обычной.

    Speed Shoes

    Если на Сонике надеты Speed Shoes и он попадает под воду, водные переменные имеют большее влияние, таким образом обнуляя все эффекты Speed Shoes. Никакие расчёты, например умножение на 0.5, не выполняются.

    Скорости анимаций

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

    P.S. для внимательных и любопытных читателей. В этой серии постов есть небольшая пасхалка, а именно — два зашифрованных английских слова. Каждая часть содержит ровно одну букву (то есть сейчас можно расшифровать уже 6 букв), всего их, как и частей, будет 14. В следующих постах я буду выкладывать подсказки, а пока первая: код содержится не в HTML, никакой стеганографии и таинственных сторонних сайтов. Ваши догадки можете присылать в личку, для рид-онли и просто читателей в профиле есть моя почта. Первому отгадавшему будет какой-нибудь приятный бонус (например, перевод интересной для него статьи). (Надеюсь, такие загадки не против правил Хабра)

    Комментарии (0)

      Let's block ads! (Why?)

      По следам Google I/O 2016 — новый Firebase: интеграция с Android

      Похоже, Github опять не доступен в России

      пятница, 8 июля 2016 г.

      Device Lab от Google: Project Tango

      Комментарии (0)

        Let's block ads! (Why?)

        [Из песочницы] Улучшение путей взаимодействия пользователя (user flow) через переходы по странице

        Пост является переводом статьи "Improving User Flow Through Page Transitions" со Smashing Magazine о создании плавных переходов. Автор этой статьи, Луиджи Де Роза, является фронт-энд разработчиком в EPIC. Далее повествование будет идти от лица автора статьи. Приятного чтения.


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


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


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


        Примеры


        Множество мобильных приложений используют отличные переходы между видами. В этом примере ниже, который следует рекомендациям Google material design, мы видим, как анимация передает иерархические и пространственные отношения между страницами.



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


        Как связать переходы между страницами


        SPA фреймфорки


        Перед тем, как пачкать наши руки, я должен что-нибудь сказать о фреймворках для одностраничных приложений (single-page application, SPA). Если вы используете SPA фреймворк (такой как AngularJS, Backbone.js или Ember), то создать переходы будет намного легче, потому что все пути обрабатываются JavaScript. В этом случае вам стоит обратиться к соответствующей документации, чтобы посмотреть на реализацию переходов между страницами во фреймворке на ваш выбор, потому что там, возможно, есть хорошие примеры и инструкции.


        Плохой способ


        Моя первая попытка создать переход между страницами выглядела примерно так:


        document.addEventListener('DOMContentLoaded', function() {
          // Animate in
        });
        
        document.addEventListener('beforeunload', function() {
          // Animate out
        });
        

        Концепция проста: Использовать анимацию, когда пользователь покидает страницу, и другую анимацию, когда новая страницы загружается.


        Однако, вскоре я заметил, что у этого решения есть ряд ограничений:


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

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


        Правильный способ


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


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


        Предотвращение поведения ссылок по умолчанию


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


        // Обратите внимание, мы намеренно привязываем наш обработчик к объекту документа
        // так, чтобы мы смогли перехватить любые якоря, добавленные в будущем.
        document.addEventListener('click', function(e) {
          var el = e.target;
        
            // Идем вверх по списку нод, пока не найдем ноду с .href (HTMLAnchorElement)
          while (el && !el.href) {
            el = el.parentNode;
          }
        
          if (el) {
            e.preventDefault();
            return;
          }
        });
        

        Этот метод добавления обработчика к родительскому элементу, вместо добавления к опреденной ноде, называется делегированием событий, которые возможны благодаря природе пузырьковых событий HTML DOM API.


        Получение страницы


        Теперь, когда мы прервали загрузку страницы браузером, мы можем вручную получить страницу используя Fetch API. Давайте посмотрим на следующую функцию, которая получает содержимое HTML страницы при получении ее URL.


        function loadPage(url) {
          return fetch(url, {
            method: 'GET'
          }).then(function(response) {
            return response.text();
          });
        }
        

        Для браузеров, которые не поддерживают Fetch API, стоит добавить полифилл, или использовать XMLHttpRequest.


        Изменение текущего URL


        У HTML5 есть фантастическое API, названное pushState, которое позволяет веб-сайтам обращаться и изменять историю браузера без загрузки каких-либо страниц. Ниже мы используем это для того, чтобы изменить текущий URL на URL следующей страницы. Заметьте, что это — модификация объявленного ранее обработчика click.


        if (el) {
          e.preventDefault();
          history.pushState(null, null, el.href);
          changePage();
        
          return;
        }
        

        Как вы могли заметить, мы также добавили вызов функции changePage, на которую мы взглянем немного детальнее. Похожая функция также будет вызвана в событии popstate, которое будет наступать при изменении активной истории браузера (например, когда пользователь нажмет кнопку назад):


        window.addEventListener('popstate', changePage);
        

        Таким образом, мы строим очень примитивную систему маршрутизации, в которой у нас есть активный и пассивный режимы.


        Активный режим наступает тогда, когда пользователь нажимает на ссылку, и мы изменяем URL используя pushState, в то время как пассивный режим наступает при изменении URL, и мы получаем уведомление от события popstate. В любом случае, мы собираемся вызвать changePage, которая позаботится о чтении нашего нового URL и загрузке страницы.


        Разбор и добавление нового содержимого


        Обычно, у страниц, по которым осуществляется переход, есть такие основные элементы как header и footer. Мы будем использовать следующую DOM структуру на всех наших страницах (которая, сама по себе, является структурой Smashing Magazine):


        <header>
          …
        </header>
        
        <main>
          <div class="cc">
             …
          </div>
        </main>
        
        <footer>
         …
        </footer>
        

        Единственная часть, которую нам нужно изменять на каждой странице — содержимое контейнера cc. Таким образом, мы можем построить нашу функцию changePage примерно так:


        var main = document.querySelector('main');
        
        function changePage() {
          // Заметьте, что URL уже изменился
          var url = window.location.href;
        
          loadPage(url).then(function(responseText) {
            var wrapper = document.createElement('div');
                wrapper.innerHTML = responseText;
        
            var oldContent = document.querySelector('.cc');
            var newContent = wrapper.querySelector('.cc');
        
            main.appendChild(newContent);
            animate(oldContent, newContent);
          });
        }
        

        Анимация!


        Когда пользователь нажимает на ссылку, функция changePage получает HTML этой страницы, затем извлекает cc контейнер и добавляет его в элемент main. На данный момент у нас есть два контейнера cc на нашей странице, первый принадлежит предыдущей страницы, а второй следующей.


        Следующая функция, animate, заботится о плавном перекрытии двух контейнеров скрывая старый, проявляя новый и удаляя старый контейнер. В этом примере я использую Web Animations API для создания анимации появления, но вы можете использовать любой другой способ или библиотеку, которая вам нравится.


        function animate(oldContent, newContent) {
          oldContent.style.position = 'absolute';
        
          var fadeOut = oldContent.animate({
            opacity: [1, 0]
          }, 1000);
        
          var fadeIn = newContent.animate({
            opacity: [0, 1]
          }, 1000);
        
          fadeIn.onfinish = function() {
            oldContent.parentNode.removeChild(oldContent);
          };
        }
        

        Итоговый код доступен на Github.



        Все это лишь основы переходов по страницам!


        Предостережения и ограничения


        Небольшой пример, который мы только что создали, далек от идеала. По факту, мы не приняли во внимание ряд вещей:


        • Убедиться, что мы затронули правильные ссылки.
          Перед изменением поведения ссылки, нам нужно добавить проверку, чтобы убедиться, что она должна быть изменена. Например, нам нужно игнорировать все ссылки с target="_blank" (которое открывает страницу в новой вкладке), все ссылки на внешние домены и некоторые другие особенные случаи, такие как Control/Command + click (которые также открывают страницу в новой вкладке).
        • Обновление элементов за пределами главного контейнера.
          В данный момент, пока страница изменяется, все элементы за пределами контейнера cc остаются прежними. Однако, некоторые из этих элементов должны быть изменены (сейчас это возможно только изменяя вручную), включая title документа, элемент меню с классом active и, потенциально, множество других зависимостей на нашем сайте.
        • Управление жизненным циклом JavaScript.
          Сейчас наша страница ведет себя примерно также, как и SPA, в котором браузер не изменяет страницу самостоятельно. Так вот, нам нужно вручную позаботиться о жизненном цикле JavaScript, например, связывая (binding) и развязывая определенные события, выполняя плагины, включая полифиллы и сторонний код.

        Браузерная поддержка


        Единственное требование для этого режима навигации — pushState API, который доступен во всех современных браузерах. Этот метод работает полностью в качестве прогрессивного улучшения. Страницы по прежнему доступны обычным способом, и web-сайт продолжит нормально работать, если JavaScript отключен.


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


        Продвигаясь дальше


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


        Использование кэша


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


        var cache = {};
        function loadPage(url) {
          if (cache[url]) {
            return new Promise(function(resolve) {
              resolve(cache[url]);
            });
          }
        
          return fetch(url, {
            method: 'GET'
          }).then(function(response) {
            cache[url] = response.text();
            return cache[url];
          });
        }
        

        Как вы могли догадаться, мы можем использовать более долговременный кэш с Cache API или другое постоянное хранилище на стороне пользователя (например IndexedDB).


        Анимация текущей страницы


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


        Используя обещания (promises), обработка таких ситуаций может показаться очень простой. Метод .all создает новое обещание, которое выполнится после того, как все обещания, переданные в виде аргументов, будут выполнены.


        // Сразу после разрешения animateOut() и loadPage()
        Promise.all[animateOut(), loadPage(url)]
          .then(function(values) {
            …
        

        Предварительная загрузка следующей страницы


        Используя навигацию PJAX, страница сменяется почти в два раза быстрее навигации по умолчанию, потому что браузеру не приходится разбирать и вычислять какие-либо скрипты или стили на новой странице.


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



        Как вы можете видеть, задержка между нажатием и наведением курсора обычно составляет от 200 до 300 миллисекунд. Этого времени обычно достаточно для загрузки следующей страницы.


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


        Другой момент, который мы могли заметить и принять во внимание, заключается в предугадывании скорости соединения пользователя. (Возможно это станет возможно в будущем с Network Information API.)


        Частичный вывод


        В нашей функции loadPage мы получаем весь HTML документ, хотя нам нужен только cc контейнер. Если бы мы использовали язык на стороне сервера, мы бы могли обнаружить, приходит ли запрос от определенного пользовательского вызова AJAX и, если так, выводить только нужный контейнер. Используя Headers API мы можем отправить пользовательский HTTP заголовок в нашем запросе.


        function loadPage(url) {
          var myHeaders = new Headers();
          myHeaders.append('x-pjax', 'yes');
        
          return fetch(url, {
            method: 'GET',
            headers: myHeaders,
          }).then(function(response) {
            return response.text();
          });
        }
        

        Затем, на стороне сервера (используя PHP в этом случае), мы можем определить, существует ли наш пользовательский заголовок перед выводом требуемого контейнера:


        if (isset($_SERVER['HTTP_X_PJAX'])) {
          // Вывод контейнера
        }
        

        Это уменьшит размер HTTP сообщений, а также уменьшит нагрузку на сервер.


        Подводя итоги


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


        Таким образом родилась Barba.js — небольшая библиотека (4 KB в сжатом состоянии), которая абстрагирует всю эту сложность и предоставляет приятный, чистый и простой API для разработчиков. Она также учитывает различные взгляды и поставляется с готовыми переходами, кэшированием, предварительной загрузкой и событиями. Библиотека имеет открытый исходный код и доступна на GitHub.



        Вывод


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


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

        Комментарии (0)

          Let's block ads! (Why?)

          Аварии на серверных фермах

          Cериалокачалка на python3 с поддержкой расширений

          Ищем уязвимости в коде: теория, практика и перспективы SAST

          [Перевод] Печатать с удовольствием

          В настоящей статье я исследую человеческие и машинные аспекты задержки при печатании (вводе с клавиатуры или «запаздывание ввода») и представляю экспериментальные данные по задержке при работе с популярными редакторами текста и кода.

          С недавних пор Задержка стала горячей темой в компьютерном мире — сейчас есть клавиатуры с малой задержкой, мониторы на 144 Гц, специальные технологии, уменьшающие время задержки (как, например, FreeSync или G-Sync), интересующиеся этим сообщества и прочее и прочее. Конечно, часть этой моды создана маркетингом, но правда в том, что малая задержка стала возможной и желательной.

          Очевидно, что геймеры — первые, кто выигрывает от таких улучшений. В некоторых областях, таких как виртуальная реальность, задержка оказывается решающим фактором, даже когда речь идёт об одной миллисекунде. Но что сказать о программистах? Нужно ли нам «печатать с удовольствием», чтобы «разрабатывать с удовольствием»? Давайте разберёмся.

          Содержание:

          1. Сторона человека
          1.1. Обратная связь
          1.2. Моторный навык
          1.3. Внутренняя модель
          1.4. Мультисенсорная интеграция
          1.5. Эффекты
          2. Сторона машины
          2.1. Входная задержка
          2.2. Задержка обработки
          2.3. Выходная задержка
          2.4. Полная задержка
          3. Сравнительные тесты редакторов
          3.1. Конфигурация
          3.2. Методология
          3.3. Windows
          3.4. Linux
          3.5. VirtualBox
          4. Выводы
          5. Ссылки

          1. Сторона человека


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

          Начнём с основ — стоит ли, вообще, беспокоиться о задержке? У нас ведь нет какой-то спешки, мы можем просто печатать, что требуется, а результат проверить позже. Несколько секунд ничего не решают, так ведь? Не совсем.

          1.1. Обратная связь


          Человек не «просто печатает», что желает; нам нужна обратная связь, чтобы выполнять эту задачу, поскольку наши чувства образуют т.н. замкнутый контур управления с нашими движениями. Зрительный образ — не только результат ввода; он является неотъемлемой частью процесса.

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

          Уменьшение задержки ведёт к «укорачиванию» петли обратной связи, благодаря чему ввод идёт легче, с большей скоростью и точностью. Пока неплохо, но где разумная граница? В конце концов, человек реагирует невероятно медленно — «путь туда и обратно» от чувств к сознанию и затем обратно к мышцам занимает около 200 мс! Несомненно, реакцию можно тренировать, и она различная у людей, но некоторая сравнительно маленькая задержка, как, например, 100 мс, вроде бы, хороший вариант, не так ли? Ничуть.

          1.2. Моторный навык


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

          Формально говоря, печатание (ввод на клавиатуре) — это процесс управления движением, осуществляемым моторной системой человека. Поскольку печатание (ввод на клавиатуре) является мелкой моторикой (происходят скоординированные движения мелких мускулов), оно сильно зависит от обратной связи. Однако эта обратная связь обрабатывается на уровне подсознания, поэтому мы необязательно будем осознавать задержку, испытывая в то же время её серьёзное отрицательное воздействие. Время реакции человека имеет значение только для исправления ошибок.

          Но даже полуавтоматические процессы ограничены зрительной задержкой (pdf-файл), и любая обратная связь хороша, только если мы можем использовать её. Системе зрения человека требуется около 40 мс, чтобы обработать ввод. Это значение также зависит от многих факторов, от конкретного человека и может быть улучшено тренировкой. Делаем вывод: задержка менее 20 мс была бы приемлемой, так? Не совсем.

          1.3. Внутренняя модель


          Прежде всего, уточним, что любая «внешняя» задержка добавляется к зрительной задержке, а не накладывается на неё, т.е. любая задержка имеет значение. Но можно аргументировать, что значение около 20 мс, всё равно, сравнительно мало. Хорошо, но моторная система человека знает несколько ловких трюков, чтобы реагировать быстрее.

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

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

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

          1.4. Мультисенсорная интеграция


          Зрительный образ является не единственным видом обратной связи при печатании на клавиатуре: мы можем также слышать звуки при нажатии на клавиши, ощущать давление на наши пальцы, воспринимать положение наших рук и пальцев (т.н. проприоцепция).

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

          Нервная система может в некоторой степени адаптироваться (pdf-файл) к постоянной задержке зрительной обратной связи (хотя и не идеально), но любые нерегулярности длительности задержки (т.н. дрожание (джиттер)) создают дополнительные проблемы из-за свойственной им непредсказуемости.

          Есть несколько показательных примеров из других областей, где задержка сигналов обратной связи может вызывать худшие последствия, чем её полное отсутствие, вплоть до ситуации, когда исходная деятельность становится вообще невозможной: если играть на MIDI-клавиатуре через компьютер, то задержки звука на 20-30 мс достаточно, чтобы нарушить ваши действия (одна статья (pdf-файл) утверждает, что имеет значение задержка звука даже прим. на 1 мс); другим хорошим примером является т.н. SpeechJammer (pdf-файл) («истребитель болтовни»), который использует задержку звука обратной связи на прим. 200 мс, временно нарушая способность человека говорить.

          1.5. Эффекты


          Соберём вместе ключевые моменты:

          • Печатание (ввод на клавиатуре) является сложным полуавтоматическим процессом, требующим годы на освоение.
          • В принципе на процесс печатания можно влиять миллисекундными задержками в зрительной обратной связи.
          • Совсем необязательно воспринимать сознанием наличие задержки, чтобы, тем не менее, она отрицательно влияла на вас.
          • Люди сильно различаются по восприимчивости и толерантности к задержке.

          Но как конкретно задержка влияет на процесс печатания (ввода на клавиатуре)? Здесь имеется несколько возможных эффектов:

          • Печатание замедляется.
          • Количество ошибок и их правок возрастает.
          • Глаза устают больше (поскольку система зрения перегружена).
          • Мышцы устают сильнее (поскольку управление движениями становится менее определённым).
          • Процесс требует более осознанного внимания.

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

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

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

          Когнитивные аспекты профессиональной машинописи
          Роль зрительной обратной связи с экрана и рук в профессиональной машинописи (pdf-файл)

          В частности, стоит процитировать следующее (источник):

          Задержка зрительной обратной связи на дисплее компьютера имеет важное воздействие на поведение оператора и на его удовлетворённость работой.

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

          2. Сторона машины


          Что происходит между моментом нажатия на клавишу и моментом появления символа на экране? Оказывается, очень много разного, и всё требует времени. Можно ли просто купить топовый компьютер, чтобы обеспечить себе спокойное печатание? Это поможет, но лишь в какой-то степени, поскольку многие части этого процесса не зависят от центрального и/или графического процессоров. Прими обе таблетки, и я покажу тебе, как глубоко уходит кроличья нора (потому что даже то, что последует, является лишь частью всей правды).

          Задержка печатания может быть разделена на следующие компоненты:

          • Входная задержка (клавиатура)
          • Задержка обработки (программное обеспечение)
          • Выходная задержка (монитор)

          Рассмотрим внимательнее каждую компоненту.

          2.1. Входная задержка


          Сначала разберёмся, как обычная неигровая USB-клавиатура обрабатывает наш ввод. Такие клавиатуры используются наиболее широко сейчас как на настольных компьютерах, так и на лэптопах.

          Сканирование клавиатуры

          Обычная клавиатура содержит более 100 клавиш, что довольно много. Чтобы минимизировать количество проводов и входов управляющего процессора, клавишные переключатели обычно соединены в матричной схеме, т.е. «строки» и «столбцы» проводов пересекаются. Благодаря этому количество проводов и входов можно уменьшить с «x * y» до «x + y» (например, со 121 до 22). Следствием такого подхода является то, что управляющий процессор не может считывать состояние всех клавиш одновременно — он должен периодически сканировать их с постоянной частотой, что ведёт к некоторой задержке. Типичная частота сканирования матрицы составляет 1 000 Гц, поэтому максимальная задержка, связанная со сканированием, равна 1 мс (средняя — 0,5 мс).

          Дребезг контактов

          Независимо от типа клавиатуры клавишные переключатели механически несовершенны и подвержены дребезгу контактов — вместо «чистого» срабатывания переключатель быстро переходит из состояния «вкл.» в состояние «выкл.» и обратно несколько раз, прежде чем остановится. Длительность дребезга зависит от технологии переключения; например, для устройств Cherry MX, как заявлено, она составляет менее 5 мс. Хотя точное распределение вероятности неизвестно, но базируясь на соответствующих эмпирических данных, можно принять длительность дребезга около 1,5 мс.

          Устранение дребезга контактов

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

          USB-опрос

          Поскольку USB является шиной, управляемой главным компьютером, то клавиатура должна ждать запрос от этого компьютера, чтобы послать данные о зарегистрированном нажатии клавиши (процессор управления клавиатурой располагает собранные события в выходном буфере). Хотя USB-устройства запрашивают требуемую частоту опроса при инициализации (до 1 000 Гц), операционные системы обычно используют 125 Гц, как для низко-, так и для полноскоростных (USB1.x) устройств; поэтому максимальная задержка, связанная с опросом, составляет 8 мс (средняя — 4 мс). Следует помнить, что часто можно повысить частоту опроса вручную.

          USB-преобразование

          Некоторое время требуется также на преобразование данных. Как для низко-, так и для полноскоростных устройств наименьшая длительность преобразования составляет 1 мс. У высокоскоростных устройств (USB2) это время много меньше — прим. 0,001 мс (кстати, имеется прекрасная статья о пригодности USB для систем реального времени (pdf-файл)). Чтобы минимизировать время преобразования данных, рекомендуется не подключать широкополосные USB-устройства (такие как, например, накопители, звуковые карты, веб-камеры) к тому же USB-контроллеру / хабу, к которому подсоединена ваша клавиатура.

          Итак, соберём значения задержки для типичной клавиатуры:

          Эти результаты, в общем, соответствуют некоторым экспериментальным результатам по измерению запаздывания, вызываемого клавиатурой.

          Можно ли сделать лучше? Конечно, проще простого! Используйте профессиональную клавиатуру:

          • переключатели с малым временем дребезга (некоторые даже оптические)
          • высокая частота сканирования матрицы
          • адаптивный алгоритм устранения дребезга
          • настраиваемое микропрограммное обеспечение
          • USB2 для быстрого опроса и малой задержки преобразования

          Всё это может значительно уменьшить как максимальное, так и среднее значение задержки клавиатуры. Например, когда я приобрёл клавиатуру Kinesis Advantage, я сразу почувствовал отличие от моей предыдущей «обычной» клавиатуры.

          Игровые клавиатуры идут даже дальше — если вы сторонник бескомпромиссного решения, то стоит рассмотреть что-то вроде технологии Cherry’s RealKey, при которой считывание клавиш идёт через аналоговые входы (а не цифровые); задержка получается почти нулевая.

          2.2. Задержка обработки


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

          Следует помнить, что задержка обработки не определяется только производительностью — теоретически можно иметь систему, выдающую 300 FPS, с «запаздыванием» 5 секунд после ввода. В частности, пакетирование и буферизация часто являются попыткой достичь более высоких рабочих характеристик за счёт задержки.

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

          Операционная система

          После того как USB-хост («USB-порт» компьютера) получает данные с клавиатуры, он инициирует аппаратное прерывание так, чтобы программный драйвер в операционной системе мог прочитать полученные данные через интерфейс хост-контроллера (обычно через PCI или PCIe). Затем эти данные обрабатывает подсистема человеко-машинного интерфейса (HID) в ОС, что в итоге приводит к помещению события «клавиша нажата» (типа WM_KEYDOWN) в очередь сообщений операционной системы. После этого событие отправляется циклом событий в окно активного приложения.

          Все эти действия требуют некоторого времени, но оно пренебрежимо мало для нашей цели (печатание на клавиатуре). Что здесь важно, так это то, что основные операционные системы (а именно — Windows, Mac и ОС на базе Linux) не являются системами реального времени, поэтому гарантия на значение задержки отсутствует. Как аппаратные процессы (сетевой ввод/вывод, ввод/вывод сохранения и т.п.), так и многозадачность программного обеспечения могут увеличить время обработки непредсказуемо (и неограниченно).

          Кстати, поскольку приложения графического пользовательского интерфейса могут накладывать жёсткие ограничения на системную задержку, было много успешных попыток оптимизировать планирование ядра Linux специально для случая «настольного» использования (в частности, через систему динамической оптимизации «ulatencyd»).

          Для простоты предположим, что наш компьютер не имеет значительной загрузки при вводе с клавиатуры; тогда задержки такого рода будут менее 1 мс.

          Виртуальная машина

          Если текстовый редактор / IDE работает поверх виртуальной машины процесса (как JVM у Java или CLR у .NET Framework), то дополнительные задержки могут возникнуть потому, что их среда выполнения также не является системой реального времени (за исключением специальных реализаций, как, например, Real time Java).

          Производительность сама по себе обычно не создаёт проблемы, но, когда включается JIT-компилятор или сборщик мусора, можно ожидать некоторое «запаздывание». Движки JavaScript и интерпретатор Emacs Lisp также порождают такой тип задержек.

          Основные виртуальные машины значительно усовершенствовались за многие годы, тем не менее, некоторый предварительный «прогрев» мог бы быть, всё же, полезным, чтобы гарантировать стабильную задержку.

          Редактор

          Эта часть — самая значимая. Используемый редактор может дать основной вклад в задержку печатания. В отличие от задержек, создаваемых аппаратурой, максимальная задержка в редакторе практически не ограничена (можно легко наткнуться на 1-2 секунды).

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

          Есть путь получше — в принципе, нам не нужен суперкомпьютер для спокойного печатания — всё, что мы должны сделать, так это реализовать использование редактора, памятуя о поставленной цели. Печатание в редакторе является сравнительно простым процессом, поэтому даже компьютеры на 286 процессоре обеспечивали довольно быстрый ввод. Вполне возможно достигнуть близкую к нулю задержку печатания даже в сложном современном IDE, что является именно тем, на что нацелен режим печатания с нулевой задержкой в IntelliJ IDEA. Технические подробности см. в моей статье об отрисовке с малой задержкой в AWT и Swing (несмотря на то, что рассматривается платформа Java, ключевые идеи могут быть распространены на большинство современных операционных систем и фреймворков для построения графических пользовательских интерфейсов).

          Редакторы/IDE сильно различаются по задержке печатания. Следующая глава содержит большое количество эмпирической информации по теме.

          Конвейер рендеринга

          Центральный и графический процессор работают параллельно и взаимодействуют через буфер команд, дополненный буфером видеодрайвера. Большинство команд рендеринга являются асинхронными. Поэтому они имеют полное право не запускаться сразу, как только отработает метод отрисовки. Команды отрисовки накапливаются в буфере видеодрайвера, затем пакетируются и направляются в буфер команд графического процессора (делается попытка получить более высокую частоту кадров за счёт задержки). Результирующая задержка, в зависимости от комбинации аппаратного обеспечения / операционной системы / программного интерфейса приложения / видеодрайвера — может меняться от незначительной до весьма существенной.

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

          Двойная буферизация

          Чтобы не показывать частично прорисованный кадр и представить изображение на экране сразу целиком, многие приложения обращаются к т.н. двойной буферизации — изображение первоначально подготавливается во внеэкранном «вторичном буфере», а когда все графические операции завершены, обновлённая область изображения передаётся в кадровый буфер путём побитового копирования или путём переключения страницы. Многие фреймворки (например, Swing) выполняют двойную буферизацию по умолчанию.

          Излишне говорить, что этот дополнительный шаг приводит к дополнительной задержке. В документации Java сказано: «Если вашей метрикой производительности является просто скорость, с которой происходит двойная буферизация или переключение страниц по сравнению с прямым рендерингом, то вы можете быть разочарованы. Может оказаться, что значения у прямого рендеринга будут намного превосходить таковые у двойной буферизации, а эти, в свою очередь, будут много выше чем у переключения страниц.»

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

          Менеджер окон

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

          стековые оконные менеджеры организуют изображение перекрывающихся окон так, что сначала выполняется прорисовка окон, расположенных сзади. В то время как у этого подхода есть некоторые недостатки (необходимость явного восстановления содержимого окна), он не вносит дополнительные задержки, потому что приложения рисуют непосредственно в кадровом буфере. Примеры стековых оконных менеджеров: Classic theme в Windows, Openbox в Linux.

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

          Соответствующие эмпирические данные приведены в следующей главе.

          Вертикальная синхронизация

          Вертикальная синхронизация или V-Sync является методом предотвращения разрыва изображения на экране, т.е. такого состояния, когда дисплей показывает информацию из нескольких кадров в одном изображении экрана. Возникающие искажения наиболее заметны на горизонтально двигающихся объектах с резкими вертикальными краями (т.е. не во время печатания).

          V-Sync сводится к ожиданию нового кадра в сгенерированном видеосигнале перед передачей содержимого вторичного буфера в кадровый буфер (таким образом, V-Sync подразумевает двойную буферизацию). Поэтому при включённой вертикальной синхронизации может быть дополнительная задержка перед обновлением кадрового буфера. Максимальная задержка составляет примерно 17 мс, средняя — около 8 мс (для частоты обновления 60 Гц). Интересно, что эта задержка связана с обновлением экрана, из-за чего её среднее полное значение возрастает только примерно на 4 мс, поскольку часть этой задержки является неустранимой (зависит от вертикальной позиции символа). Максимальное увеличение полной задержки достигает, всё же, примерно 17 мс.

          Среды рабочего стола обычно не позволяют явно выбирать, включать или нет V-Sync. V-Sync в Windows разрешена в Aero, но запрещена в Classic theme. V-Sync в Linux, кажется, выключена, как в композитных, так и в стековых оконных менеджерах.

          В некотором смысле V-Sync вынуждает графический процессор адаптироваться, чтобы контролировать частоту обновления, что является наследством эры электронно-лучевых трубок. В настоящее время имеются намного более предпочтительные решения (см. ниже).

          Рассмотрим значения задержки для типичного компьютера (принимаем, что значительные нагрузки на ввод/вывод и вычислитель отсутствуют и что используется стековый менеджер окон без V-Sync):

          Эти задержки намного менее предсказуемы, чем задержки, вызванные аппаратными средствами, и они очень чувствительны к конфигурации компьютера. В принципе полная задержка обработки может быть как 0-1 мс, так и 10 с. Вот почему теоретических размышлений здесь недостаточно и нужны некоторые точные цифры — см. в следующей главе обширные эмпирические данные.

          Как можно улучшить ситуацию с задержкой обработки? Здесь есть несколько путей:

          • Редактор/IDE с малой задержкой
          • Мощное аппаратное обеспечение компьютера (центральный и графический процессоры)
          • Стековый менеджер окон (Classic Windows theme, Openbox и т.п.).
          • Отсутствие вертикальной синхронизации

          Очевидно, что редактор имеет самое большое значение.

          2.3. Выходная задержка


          Рассмотрим, как типичный неигровой жидкокристаллический монитор показывает сгенерированное изображение.

          Обновление экрана

          Изображение экрана компьютера хранится в кадровом буфере в памяти видеокарты (или в разделяемой видеопамяти). Монитор не имеет прямого доступа к кадровому буферу; вместо этого видеоконтроллер генерирует видеосигнал, передаваемый через видеоинтерфейс (такой как VGA, DVI, HDMI, DisplayPort и т.д.), благодаря чему монитор может непрерывно обновлять свой внутренний буфер изображения. Эта передача происходит с фиксированной частотой, называемой частотой обновления, которая для обычных ЖК-мониторов равна 60 Гц. Поэтому можно ожидать, что максимальная задержка, связанная с обновлением, равна примерно 17 мс, а средняя — примерно 8 мс (поскольку нам требуется показать только новый введённый символ, то можно не учитывать время, требуемое для передачи полного кадра).

          Запаздывание дисплея

          В отличие от ЭЛТ-монитора, который должен показать входящее изображение немедленно (потому что его единственная «память» — послесвечение люминофора), ЖК-монитор имеет свой собственный буфер для хранения изображения. В принципе это делает возможным задержать показ входящего изображения, чтобы изменить размеры, выполнить деинтерлейсинг или как-то «улучшить» его (или просто получить полный кадр, прежде чем обновить пиксели). Возникающая задержка известна как запаздывание дисплея (или «запаздывание ввода монитора»). Это явление получило широкую огласку в последнее время, но оно всё ещё является довольно спорной темой. Измерения запаздывания дисплея часто являются неправильными, т.к. трудно отделить это запаздывание от времени отклика пикселя (см. прекрасный отчёт Prad по запаздыванию ввода, чтобы понять, как делать это правильно). Хотя в худшем случае задержка может быть 2-3 кадра (т.е. до 50 мс при частоте обновления 60 Гц), запаздывание ввода представлено, в основном, в телевидении высокой чёткости, а не в мониторах компьютеров; поэтому можно принять, что эта задержка близка к нулю для типичных мониторов. Тем не менее, хорошей идеей будет выключить все «корректоры изображения» на вашем мониторе (как ни странно, и овердрайв тоже).

          Отклик пикселя

          Пиксели ЖК-дисплея не могут реагировать на изменения управляющего напряжения немедленно. Интервал времени, требуемый для изменения пикселя на дисплее, называется временем отклика пикселя. Это время зависит, в основном, от технологии ЖК-матрицы (TN, IPS, VA и т.д.). ЖК-мониторы прошли длинный путь, снижая время отклика пикселя, и современные TN-мониторы (используемые наиболее широко в настоящее время) имеют среднее время отклика всего лишь около 4 мс.

          Итак, соберём значения задержки для типичного компьютерного монитора:

          Можно ли уменьшить выходную задержку? Здесь имеется несколько надёжных методов:

          • Игровой монитор, обеспечивающий малое запаздывание дисплея и более быстрый отклик пикселя.
          • Монитор с частотой обновления 144 Гц (задержка, связанная с обновлением, равна 3,5 мс).
          • Комбинация видеокарты и монитора, которая поддерживает Adaptive-Sync, FreeSync или G-Sync с динамической частотой обновления (до 240 Гц) и синхронные обновления.

          Все эти меры могут снизить полную выходную задержку до прим. 1-2 мс.

          2.4. Полная задержка


          Просуммируем средние задержки во всех компонентах задержки печатания:

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

          Входная и выходная компоненты задержки строго определяются периодическими аппаратными процессами, которые могут быть оценены с высокой точностью. Эти задержки не зависят от производительности центрального и графического процессоров и имеют предсказуемые верхние границы. Типичная средняя задержка клавиатуры и монитора вместе составляет около 26 мс, что само по себе немного, но если её добавить к задержке обработки, то задержка редактора будет более заметной. Даже задержка ввода/вывода сама по себе уже превышает порог человеческого восприятия.

          Задержка обработки в отличие от задержек ввода/вывода определяется, в первую очередь, вычислениями центрального и графического процессоров, поэтому она зависит от аппаратного обеспечения и имеет практически неограниченное максимальное значение. Невозможно предсказать задержку обработки; требуется выполнить надлежащие сравнительные тесты, чтобы получить эти данные. Теоретически идеальная задержка обработки может быть близка к 0-1 мс.

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

          3. Сравнительные тесты редакторов


          Чтобы экспериментировать с измерением задержки обработки, я подготовил «Typometer» — инструмент для определения и анализа зрительной задержки текстовых редакторов (источники).

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

          3.1. Конфигурация


          Здесь описана конфигурация аппаратного и программного обеспечения, использованная для тестирования:

          Аппаратное обеспечение:

          • ЦПУ: Intel Core i5 3427U, 1,8/2,8 ГГц, кэш 3Mб
          • Графика: Intel HD 4000 (драйвер v10.18.10.3958)
          • Память: 4 Гб DDR3
          • Дисплей: 1920 x 1080, 32 бита, 59,94 Гц

          Программное обеспечение:

          Microsoft Windows 7 HP x64 SP1 6.1.7601
          Lubuntu Linux 15.10 Desktop amd64
          VirtualBox 5.0.10 на Windows (установки по умолчанию, полноэкранный режим)

          Редакторы:

          Atom 1.1
          Eclipse 4.5.1
          Emacs 24.5.1
          Gedit 3.10.4
          GVim 7.4.712
          IntelliJ Idea CE 15.0
          Netbeans 8.1
          Sublime Text 3083

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

          Были выбраны только те редакторы, которые обеспечивают, как минимум, подсветку синтаксиса. Несомненно, Notepad (Блокнот) — самый быстро реагирующий редактор, но было бы просто несправедливо сравнивать его с любым практически полезным редактором.

          Дополнительно были исключены случаи работы редактора в терминале, поскольку терминал может сам существенно влиять на задержку печатания. Кстати, современные ОС больше не поддерживают настоящий текстовый режим — как консоль Windows, так и виртуальная консоль Linux (через Alt+Fn) моделируются поверх графического кадрового буфера.

          Анализ был выполнен в R. Графики были представлены при помощи ggplot2.

          3.2. Методология


          Все редакторы/IDE работали с настройками по умолчанию, окна приложений были максимизированы.

          Редактор работал либо с пустым текстовым файлом, либо с XML-файлом (точнее, с Maven-схемой). XML был выбран потому, что он подсвечивается во всех редакторах и не зависит от других файлов проекта.

          Typometer использовал следующие параметры:

          • Количество символов: 200
          • Задержка: 150 мс
          • Доступ: нативный
          • Режим: синхронный

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

          Был использован классический оконный менеджер в Windows, поскольку, как было сказано выше, композитинг, осуществляемый в Aero, увеличивает задержку рендеринга и принудительно включает вертикальную синхронизацию (тесты показали, что Aero theme, действительно, делает все редакторы менее восприимчивыми). Здесь дано сравнение тестов GVim (один из самых быстрых редакторов вообще) в Classic theme и в Aero (пунктирные линии на 16,68 и 33,37 мс):

          Влияние Windows Aero на задержку прорисовки (GVim)

          Можно видеть, что Aero вносит, как минимум, одну кадровую задержку (прим. 16,7 мс для частоты обновления 60 Гц) и ведёт к дискретизации по времени. Это скрывает внутреннюю производительность редактора и искажает процесс сравнительного тестирования. Как я указывал ранее, задержки видеосигнала, создаваемые вертикальной синхронизацией, немного меньше задержек в кадровом буфере, но средняя разница составляет лишь 4 мс, а максимальная добавляемая задержка равна, всё же, 17 мс (для 60 Гц). Поскольку эффект довольно существенный, люди часто обнаруживают добавленную задержку «невооружённым глазом» в тестах на время реакции человека.

          График также демонстрирует, что Typometer имеет очень хорошую точность измерения задержки — нижние значения находятся так близко к теоретическому 16,68335, что это выглядит почти как результат математического расчёта.

          Как для Linux, предпочтение было отдано Lubuntu вместо Ubuntu по той же причине — Compiz даёт дополнительную задержку в прорисовку приложения. Здесь представлен график (с медианными линиями):

          Влияние Linux Compiz на задержку прорисовки (GVim)

          Средняя внесённая задержка составляет прим. 8 мс, что лучше значения у Aero; здесь также отсутствует дискретизация, вызываемая синхронизацией (но здесь наблюдается рост джиттера). Поскольку V-Sync не используется, то задержки видеосигнала находятся на уровне задержек в кадровом буфере. Предпочтительнее использовать стековый менеджер окон (типа Openbox), чтобы получить более высокую точность измерения.

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

          Несмотря на богатое разнообразие наблюдаемых зависимостей, можно выделить следующие типичные временные ряды:

          Типичные временные ряды задержки редактора

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

          Сложные редакторы (и редакторы, работающие поверх виртуальной машины / интерпретатора) в дополнение к более высокой средней задержке часто имеют тенденцию к более высокой изменчивости задержки (джиттер).

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

          3.3. Windows


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

          Текстовый файл

          Посмотрим итоговую таблицу (отсортировано по среднему значению задержки). SD означает здесь среднеквадратическое отклонение, используемое как мера джиттера. Учтите, что здесь представлена «идеальная» ситуация — простой пустой файл без выделения. Любая другая конфигурация показала бы более высокие задержки по определению.

          Задержка редактора в Windows (текстовый файл):

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

          Есть более удобный способ, который также и выглядит лучше, — можно графически изобразить значения на горизонтальной оси с некоторым добавленным случайным вертикальным сдвигом, чтобы показать распределение (имеется дополнительная информация о таком подходе). Результирующая диаграмма является простой и описательной и позволяет сравнивать различные наборы данных:

          Задержка редактора в Windows (текстовый файл)

          Очевидно, редакторы не созданы равными (по крайней мере, по задержке).

          Во-первых, средняя задержка различается значительно — более простые редакторы имеют тенденцию к более низкой задержке. Победителем является GVim, но и IDEA со включенным режимом нулевой задержки находится очень близко к GVim. Все редакторы на базе JVM (в т.ч. IDEA в режиме по умолчанию) находятся внизу, что вполне предсказуемо, уступая только Atom, т.к. работа Chrome оказалась ещё более вялой.

          Другим заметным отличием является джиттер — «лёгкие» редакторы демонстрируют очень стабильную задержку, тогда как сложные, наоборот, имеют намного более широкий разброс значений. IDEA в режиме по умолчанию показывает самый большой разброс задержки с высоким максимальным значением.

          Гистограмма ниже демонстрирует подробное воздействие режима нулевой задержки в IntelliJ IDEA:

          Влияние режима нулевой задержки в Windows (текстовый файл)

          Режим нулевой задержки сказывается положительно, снижая среднюю задержку и устраняя джиттер (но не полностью).

          XML-файл

          Ясно, что предыдущий набор является слишком «искусственным»; в конце концов, для редактирования пустого файла без какой-либо подсветки синтаксиса можно взять просто Notepad. Для чего-то более серьёзного используют другой редактор. Выполним ввод в сравнительно большом XML-файле, чтобы увидеть, как изменятся значения:

          Влияние типа содержания на задержку редактора (Windows)

          Ух ты! Различие довольно заметное и одновременно необычное. Некоторые редакторы — GVim и IDEA в режиме нулевой задержки — ну, просто, «крутые парни», им «по барабану». Однако у большинства редакторов задержка равномерно возросла. Средняя задержка в IDEA слегка уменьшилась (что несколько странно), но максимальная — увеличилась. Наиболее сильное изменение произошло у Emacs, задержка которого просто взлетела в небо.

          Энергосбережение

          Теперь отсоединимся от сети электропитания и будем работать от аккумуляторов в режиме энергосбережения.

          Задержка редактора в Windows (XML-файл, энергосбережение):

          Рассмотрим подробнее, как это повлияло на задержки:

          Влияние режима энергосбережения на задержку редактора (Windows, XML-файл)

          На большинстве редакторов это заметно не сказалось, но есть пара примечательных исключений: IDEA и Netbeans. У IDEA максимальная задержка взлетела к 240 мс, что, вполне очевидно, выше порога «ощутимости».

          Здесь показано, как режим нулевой задержки сказывается в данных условиях:

          Влияние режима нулевой задержки в Windows (XML-файл, энергосбережение)

          И снова, хотя он не устраняет джиттер полностью, воздействие значительное.

          3.4. Linux


          Продолжим наши наблюдения в Linux, пропустив для простоты синтетический тест с пустым файлом.

          Задержка редактора в Linux (XML-файл):

          Дополнительная диаграмма с подробным распределением задержки:

          Задержка редактора в Linux (XML-файл)

          Сравнение с предыдущими результатами в Windows:

          Влияние ОС на задержку редактора (XML-файл)

          Общей особенностью является то, что джиттер в Linux заметно выше для большинства редакторов (за исключением режима нулевой задержки в IDEA, где джиттер фактически уменьшился).

          Emacs и Atom выигрывают в Linux — их средняя задержка здесь заметно меньше.

          У GVim, Sublime Text, Eclipse и IDEA (в режиме по умолчанию), наоборот, задержка в Linux намного возросла. Наиболее сильное воздействие испытала IDEA — максимальная задержка достигла 200 мс даже в режиме обычного питания. Время реакции Eclipse также сильно пострадало.

          Печатание в IDEA в режиме нулевой задержки является, конечно, победителем (здесь IDEA обошёл даже GVim).

          Влияние режима нулевой задержки в Linux (XML-файл)

          Режим нулевой задержки в Linux демонстрирует низкую и исключительно стабильную задержку.

          3.5. VirtualBox


          Теперь предположим, например, что мы используем Windows, прежде всего, для игр, а работаем на виртуальной машине Linux (действительно, почему бы и нет?). Как изменятся задержки редактора в такой ситуации использования? Посмотрим.

          Задержка редактора в Linux (VirtualBox, XML-файл):

          Здесь дано сравнение с предыдущими «естественными» результатами:

          Влияние виртуализации на задержку редактора (Linux, XML-файл)

          Помимо дискретизации задержки (вызываемой либо вертикальной синхронизацией, либо другим видом дискретной синхронизации буфера) мы можем видеть постоянный рост задержки для всех редакторов. Распределения сильно не изменяются, что легко объяснимо (базовые алгоритмы сохраняются при визуализации). Максимальная задержка в IDEA выросла до 350 мс.

          Энергосбережение

          Чтобы получить полную картину, переключимся на аккумуляторы. Режим энергосбережения вместе с VirtualBox является, вероятно, самой напряжённой комбинацией для задержки редактора.

          Задержка редактора в Linux (VirtualBox, XML-файл, энергосбережение):

          Н-да, такие задержки просто нелепы! Максимальная задержка теперь превышает полсекунды!!!

          Для наглядности давайте сравним эти данные с результатами при идеальных условиях:

          Влияние конфигурации на задержку редактора

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

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

          Влияние режима нулевой задержки в VirtualBox (Linux, XML-файл, энергосбережение)

          Интересно, что в режиме нулевой задержки IntelliJ IDEA превосходит все другие редакторы (и, кстати, консольные редакторы тоже).

          4. Выводы


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

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

          Печатайте с удовольствием!

          5. Ссылки


          Смотрите также:

          Typometer — инструмент для измерения и анализа зрительной задержки в редакторах текста/кода.
          Процесс отрисовки с малой задержкой в AWT и Swing — детальный анализ источников задержки в архитектурах AWT и Swing, методов значительного снижения задержки прорисовки.

          Комментарии (0)

            Let's block ads! (Why?)

            В борьбе с раком: мультидисциплинарный подход

            Визуализация финансовых данных. Митап Минфина с разработчиками, журналистами и дизайнерами

            9 ¾ действительно полезных советов по работе с большими проектами


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

            Но случается и так, что мы беремся за работу над большими проектами. Под «большими» я понимаю композицию следующих факторов:

            1. Более 50 проектов в solution’е. Назначение не всех из них вы знаете
            2. Билд и выкладка длятся более 5 минут
            3. Над кодом работают десятки или сотни человек в разных офисах (возможно и странах)
            4. Существует четкое разделение труда и область ответственности каждой команды
            5. Существуют строгие регламенты, стандарты оформления кода, прохождение ревью является обязательным критерием выполнения задачи
            6. Учет рабочего времени производится позадачно, анализируются причины расхождения оценок и реальных трудозатрат

            Бюрократия в этом случае – необходимое зло, тем ни менее, действующее на нервы. Чтобы избежать потерь драгоценных клеток я советую сразу подготовиться к тому, что придется поменять свой привычный workflow. Хорошая новость состоит в том, что, переучившись, вам не составит труда поступать также и на небольших проектах. Скорее всего, ваши коллеги будут приятно удивлены такой педантичностью

            1. Используйте feature-бренчи и атомарные коммиты


            Совет из разряда капитанских, однако если бы все соблюдали это правило статьи вроде этой не набирали бы столько плюсов. Я не учился этой технике специально, просто в какой-то момент стал четко делить работу на подзадачи и по завершению каждой делать коммит. Использовать атомарные коммиты проще вместе с TDD, потому что сама разработка в этом случае ведется итерационно. Дополнительный бонус для вас состоит в том, что если вы сами накосячите в свой ветке, просто сделаете git reset --hard. Воспринимайте это как обязательные сохранения в сложных компьютерных играх.
            Если коллеге в другой ветке потребуется ваш код, который еще не закончен он сможет не доживаясь мерджа сделать cherry-pick и забрать только интересующие его изменения, а не весь ваш «поток сознания».
            Основной аргумент, который я слышу против этой практики «теряется состояние потока». Не могу его прокомментировать, потому что «состояние потока» нельзя измерить, потрогать и оценить.

            2. Используйте формат именования коммитов


            Именование коммитов следует начинать с ID задачи в трекере. Все современные системы управления проектами умеют синхронизироваться с билд-сервером и VCS. Кроме этого, проще отслеживать историю в репозитории.

            3. Заведите алиасы в git для подготовки pull request


            Всегда необходимо запушить все локальные коммиты в upstream, смержиться с master/dev-веткой. Это простые действия, но после заврешения работы над сложной задачей внимания может не хватать. Лучше поручить это автоматике.

            4. Заведите себе чек-лист с распорядком дня


            Например, такой:
            1. Проверить пул-реквесты, все ли прошли, нет ли отклоненных?
            2. Перевести задачу с отклоненным пул-реквестом в статус «разработка», назначить себя assignee, если там остался ревьюер или поле пустое
            3. Исправить отклоненные pull request’ы, перевести задачу в ревью, переоткрыть пул-реквест
            4. Взять задачу о которой договорились на сегодня в работу, перевести в статус разработка
            5. По завершению работы подмержить master/dev
            6. Исправить конфликты
            7. Провести smoke-тестирование
            8. Перевести задачу в ревью, открыть PR
            9. Перейти к следующей задаче

            В некоторых организациях есть сильные dev-ops и достаточно запушить в upstream первый коммит, чтобы карточка перешла в нужный статус автоматически. Я всячески приветствую такие механики, но далеко не все и не везде настраивают такие автоматизации.

            5. Договаривайтесь обо всем заранее


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

            6. Подумайте о плане B


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

            7. RTFM


            Серьезно, прочитайте. Это сэкономит время и нервы вам и вашим коллегам. Только… не доверяйте документации на все 100%. Документация никогда не бывает актуальной:)

            8. Выстраивайте партнерские взаимоотношения с коллегами


            Изучите, с кем вам предстоит взаимодействовать. Кто может вас заблокировать? Чьи распоряжения вы должны выполнять, а чьи нет? Кто может вам помочь в случае чего? Вам необязательно любить всех коллег, просто ведите себя по-человечески. Не вредничайте и не хамите. Испорченные отношения с другими сотрудниками могут аукнуться самым неожиданным образом.

            9. В любой непонятной ситуации действуйте формально


            Нет, я не призываю к итальянской забастовке. Чем больше компания, тем меньше времени у руководства вникать в детали возникших проблем. Возможно вы геройски себя проявили и пытались изо всех сил исправить ситуацию. Если этого не вышло по голове вас не по гладят. И премию не дадут. И вообще вы останетесь крайним. Делайте все, что от вас зависит, но в рамках правил. В большинстве случаев, как бы вам не казалось, они разумны. Если правила не разумны – смените работу.

            9 ¾. Будьте аккуратнее и предусмотрительнее, чем обычно


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

            Комментарии (0)

              Let's block ads! (Why?)