-Поиск по дневнику

Поиск сообщений в rss_rss_hh_full

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 17.03.2011
Записей:
Комментариев:
Написано: 1

Habrahabr








Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://habrahabr.ru/rss/.
Данный дневник сформирован из открытого RSS-источника по адресу http://feeds.feedburner.com/xtmb/hh-full, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

iOS+Kotlin. Что можно сделать сейчас

Понедельник, 25 Сентября 2017 г. 09:17 + в цитатник
adev_one сегодня в 09:17 Разработка

iOS+Kotlin. Что можно сделать сейчас

    В ветке master проекта Kotlin Native появился пример uikit. Это простое приложение под iOS, которое выводит на экран строку, введённую в поле ввода, и да, 100% кода написано на Kotlin. Выглядит оно так:



    Стоит ли думать о порте своего приложения уже сейчас?


    Да, но только если:
    0). Вам действительно нужна общая кодовая база мобильных приложений.
    1). Приложение мало завязано на платформу.
    2). У Вас есть время на написание некоторого количества кода на Kotlin, который в будущем стоит переписать на Objective-C или Swift.

    Причины пока не портировать


    ViewController, AppDelegate и даже main-функция в примере написаны на Kotlin. Те файлы, которые написаны на Objective-C нужны только чтобы XCode не выдавал ошибку и не включаются в конечную сборку (я не нашёл способов исправить положение). Т.е. полноценный interop как с Java, видимо, пока что, недоступен. Это совсем не значит, что положение дел не изменится к релизу (сейчас проект на стадии alpha preview, а об этом примере даже поста в блоге не было). Но спектр доступных сейчас возможностей довольно ограничен.

    Interop


    Идиоматический подход к написанию мультиплатформенного приложения на Kotlin — отдельно написать общую часть, отдельно — часть для каждой платформы. При этом на каждой платформе, по задумке, должны быть легко доступны все библиотеки, под неё написанные. В случае с Java работает хорошо. В случае с iOS дела сейчас обстоят следующим образом:

    @ExportObjCClass
    class KotlinViewController : UIViewController {
    
        constructor(aDecoder: NSCoder) : super(aDecoder)
        override fun initWithCoder(aDecoder: NSCoder) = initBy(KotlinViewController(aDecoder))
    
        @ObjCOutlet
        lateinit var label: UILabel
    
        @ObjCOutlet
        lateinit var textField: UITextField
    
        @ObjCOutlet
        lateinit var button: UIButton
    
        @ObjCAction
        fun buttonPressed() {
            label.text = "Konan says: 'Hello, ${textField.text}!'"
        }
    }

    То есть вполне неплохо. К каждому внешнему классу добавляем аннотацию @ExportObjCClass, к каждому графическому элементу из storyboard — @ObjCOutlet и @ObjCAction для каждого action. Классы на Objective-C доступны по их оригинальным именам.

    Если нужно вызвать Kotlin из Objective-C/Swift


    В этой статье описано, как это можно сделать. Через некоторое количество прослоек, с ручным преобразованием типов 2 раза, но зато можно звать Swift из Kotlin и Kotlin из Swift.

    Overhead


    В теории, вес приложения должен увеличиться примерно на 100 кб (отсюда).
    Вместо GC будет использоваться ARC, так что особой разницы в производительности со Swift быть не должно.

    Обратная совместимость


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

    inline


    Для реализации сопрограмм, которые делают так, чтобы синхронный и асинхронный код выглядели почти одинаково в язык было введено всего одно новое ключевое слово suspend, чем разработчики заслуженно гордятся. Но для того чтобы методы-расширения (forEach, map...) работали так же быстро, как и обычный for (и для вывода общих типов во время исполнения программы), было введено целых 3 (inline, crossinline, noinline). Они явно не делают код читаемее. JIT теряет часть возможностей для оптимизации (подкаст об этом), а опыт C показывает, что разработчики не умеют правильно пользоваться такими возможностями языка. В целом, не понимаю, почему то же самое нельзя было сделать аннотацией. Для меня inline выглядит как плохое решение достойной проблемы.

    Заключение


    — На Kotlin скоро можно будет писать под все 3 основные платформы (Android, iOS, Web).
    — Скорее всего, будет хорошая совместимость с Objective-C и Swift. Возможно лучше, чем та, что есть между этими языками. Учитывая опыт JetBrains в разработке компиляторов и IDE, в это можно поверить.
    — У Kotlin легковесный Runtime языка под Android и Web. Под iOS, судя по всему, тоже будет не тяжёлым.
    — Уже сейчас можно что-нибудь написать.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/337958/


    Метки:  

    [Перевод] Overview of Cryptoeconomics. Перевод статьи

    Понедельник, 25 Сентября 2017 г. 08:24 + в цитатник
    NikMelnikov сегодня в 08:24 Разработка

    Overview of Cryptoeconomics. Перевод статьи

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

    Наука о криптографии существует уже тысячелетия, но в формальной и систематизированной форме — всего пару десятилетий, и может быть определена как исследование коммуникации в состязательной среде (Rabah, 2004).


    Аналогичным образом, мы можем определить криптоэкономику как концепцию, которая идет на один шаг дальше, т.е., изучение экономического взаимодействия в состязательной среде (Davidson, De Filippi & Potts,2016; Ernst, 2016). Чтобы отличить себя от традиционной экономики, которая, безусловно, изучает, как экономическое взаимодействие, так и противодействие, криптоэкономика обычно фокусируется на взаимодействиях, которые происходят по сетевым протоколам. Отдельные области криптоэкономики включают:
    • Онлайн доверие и репутацию систем;
    • Крипто-токены/ криптовалюты, и, в целом, цифровые активы;
    • Смарт-контракты;
    • Согласованные алгоритмы;
    • Алгоритмы анти-спама и алгоритмы, устойчивые к атакам Сибиллы;
    • Активизированные рынки для вычислительных ресурсов;
    • Децентрализованные системы социального обеспечения /соц. помощи/ основного дохода; Децентрализованное управление (как для коммерческих, так и для некоммерческих организаций).


    В течение нескольких последних лет мы стали свидетелями роста криптоэкономики,
    что в значительной мере связано с увеличением количества криптовалют и цифровых токенов, которые привносят новые и интересные аспекты в такую науку как криптография (Potts, Davidson & De Filippi, 2016). Немногим ранее криптография была, по большому счету, простой вычислительной и информационной теоретической наукой, безопасность которой считали наиболее близкой к абсолютной.

    Как только деньги попадают в поле зрения, идеальный мир математики должен взаимодействовать с реальным миром и социальными структурами общества, экономическими стимулами, относительной верой и многими уязвимостями, которые возможно только уменьшить,
    но не удалить полностью. В то время, как криптографы привыкли к допущению типа «этот алгоритм гарантированно будет нерушимым при условии, что основные математические проблемы остаются неизменными», мир криптоэкономики вынужден довольствоваться неясными эмпирическими факторами, такими как, сложность при большом количестве атак, достаточное количество бескорыстных, а также заинтересованных в прибыли сторон, уровень концентрации различных ресурсов, и даже учитывать социально-культурные условия (Ernst, 2016; Davidson, De Filippi & Potts, 2016).

    Напротив, в традиционной прикладной криптографии, меры безопасности склоняются к виду:
    — Никто не может выполнить более чем 279 вычислительных шагов;
    — Факторные операции остаются неизменными (т.е. полиномиальными) (Rabah,2005);
    — Принятые n-ные корни композитных модулей неизменны;
    — Задача дискретного логарифма эллиптической кривой не может быть решена быстрее, чем в 2n/2 раза;

    С другой стороны, в криптоэкономике, основные меры безопасности от которых мы зависим выглядят примерно следующим образом (Ernst, 2016):
    — Никто из лиц, контролирующих более 25% всех вычислительных ресурсов не могут вступать в сговор;
    — Никто из лиц, контролирующих более 25% всех денежных ресурсов не могут вступать в сговор;
    — Сумма вычислений определенного доказательства рабочей функции, которая может быть выполнена с заданной суммой денежных средств, не является сверхлинейной за пределами точки, которая расположена достаточно низко.
    — Существует незначительное количество альтруистов и такое же незначительное количество сумашедших или политических оппонентов, поэтому большинство пользователей могут быть смоделированы как экономически рациональные.
    — Количество пользователей в системе великое множество, и в любой момент пользователи могут появляться и исчезать, в то же время, по крайней мере, некоторые из них будут постоянными.
    — Цензура невозможна, и передача сообщений между двумя узлами происходит относительно быстро.
    — Достаточно легко сгенерировать множество IP-адресов, которые дают неограниченную
    пропускную способность сети.
    — Большинство пользователей анонимны, в связи с этим негативная репутация и появление долгов практически неосуществимы.

    В связи с этим важно отметить, что существуют дополнительные предположения, касающиеся безопасности, характерные для возникающих проблем. Таким образом, нередко, даже невозможно, с уверенностью сказать, что возникшая проблема решена. Правильнее будет сказать, что необходимо будет создавать пути решения, оптимизированные для конкретных эмпирических и социальных реалий, и со временем продолжать их оптимизировать. (Ernst, 2016).
    Перевод осуществляла Елена Логачева, корректировал Никита Мельников.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/338638/


    Метки:  

    [Перевод] Overview of Cryptoeconomics. Перевод статьи

    Понедельник, 25 Сентября 2017 г. 08:24 + в цитатник
    NikMelnikov сегодня в 08:24 Разработка

    Overview of Cryptoeconomics. Перевод статьи

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

    Наука о криптографии существует уже тысячелетия, но в формальной и систематизированной форме — всего пару десятилетий, и может быть определена как исследование коммуникации в состязательной среде (Rabah, 2004).


    Аналогичным образом, мы можем определить криптоэкономику как концепцию, которая идет на один шаг дальше, т.е., изучение экономического взаимодействия в состязательной среде (Davidson, De Filippi & Potts,2016; Ernst, 2016). Чтобы отличить себя от традиционной экономики, которая, безусловно, изучает, как экономическое взаимодействие, так и противодействие, криптоэкономика обычно фокусируется на взаимодействиях, которые происходят по сетевым протоколам. Отдельные области криптоэкономики включают:
    • Онлайн доверие и репутацию систем;
    • Крипто-токены/ криптовалюты, и, в целом, цифровые активы;
    • Смарт-контракты;
    • Согласованные алгоритмы;
    • Алгоритмы анти-спама и алгоритмы, устойчивые к атакам Сибиллы;
    • Активизированные рынки для вычислительных ресурсов;
    • Децентрализованные системы социального обеспечения /соц. помощи/ основного дохода; Децентрализованное управление (как для коммерческих, так и для некоммерческих организаций).


    В течение нескольких последних лет мы стали свидетелями роста криптоэкономики,
    что в значительной мере связано с увеличением количества криптовалют и цифровых токенов, которые привносят новые и интересные аспекты в такую науку как криптография (Potts, Davidson & De Filippi, 2016). Немногим ранее криптография была, по большому счету, простой вычислительной и информационной теоретической наукой, безопасность которой считали наиболее близкой к абсолютной.

    Как только деньги попадают в поле зрения, идеальный мир математики должен взаимодействовать с реальным миром и социальными структурами общества, экономическими стимулами, относительной верой и многими уязвимостями, которые возможно только уменьшить,
    но не удалить полностью. В то время, как криптографы привыкли к допущению типа «этот алгоритм гарантированно будет нерушимым при условии, что основные математические проблемы остаются неизменными», мир криптоэкономики вынужден довольствоваться неясными эмпирическими факторами, такими как, сложность при большом количестве атак, достаточное количество бескорыстных, а также заинтересованных в прибыли сторон, уровень концентрации различных ресурсов, и даже учитывать социально-культурные условия (Ernst, 2016; Davidson, De Filippi & Potts, 2016).

    Напротив, в традиционной прикладной криптографии, меры безопасности склоняются к виду:
    — Никто не может выполнить более чем 279 вычислительных шагов;
    — Факторные операции остаются неизменными (т.е. полиномиальными) (Rabah,2005);
    — Принятые n-ные корни композитных модулей неизменны;
    — Задача дискретного логарифма эллиптической кривой не может быть решена быстрее, чем в 2n/2 раза;

    С другой стороны, в криптоэкономике, основные меры безопасности от которых мы зависим выглядят примерно следующим образом (Ernst, 2016):
    — Никто из лиц, контролирующих более 25% всех вычислительных ресурсов не могут вступать в сговор;
    — Никто из лиц, контролирующих более 25% всех денежных ресурсов не могут вступать в сговор;
    — Сумма вычислений определенного доказательства рабочей функции, которая может быть выполнена с заданной суммой денежных средств, не является сверхлинейной за пределами точки, которая расположена достаточно низко.
    — Существует незначительное количество альтруистов и такое же незначительное количество сумашедших или политических оппонентов, поэтому большинство пользователей могут быть смоделированы как экономически рациональные.
    — Количество пользователей в системе великое множество, и в любой момент пользователи могут появляться и исчезать, в то же время, по крайней мере, некоторые из них будут постоянными.
    — Цензура невозможна, и передача сообщений между двумя узлами происходит относительно быстро.
    — Достаточно легко сгенерировать множество IP-адресов, которые дают неограниченную
    пропускную способность сети.
    — Большинство пользователей анонимны, в связи с этим негативная репутация и появление долгов практически неосуществимы.

    В связи с этим важно отметить, что существуют дополнительные предположения, касающиеся безопасности, характерные для возникающих проблем. Таким образом, нередко, даже невозможно, с уверенностью сказать, что возникшая проблема решена. Правильнее будет сказать, что необходимо будет создавать пути решения, оптимизированные для конкретных эмпирических и социальных реалий, и со временем продолжать их оптимизировать. (Ernst, 2016).
    Перевод осуществляла Елена Логачева, корректировал Никита Мельников.
    Original source: habrahabr.ru (comments, light).

    https://habrahabr.ru/post/338638/


    Метки:  

    Библиотека быстрого поиска путей на графе

    Понедельник, 25 Сентября 2017 г. 07:01 + в цитатник
    anvaka сегодня в 07:01 Разработка

    Библиотека быстрого поиска путей на графе

      Привет, Друзья!


      Я написал библиотеку поисков путей на произвольных графах, и хотел бы поделиться ей с вами: http://github.com/anvaka/ngraph.path


      Пример использования на огромном графе:





      Поиграться с демо можно здесь: https://anvaka.github.io/ngraph.path.demo/


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


      Описание разных вариантов A* уже не раз встречалось на хабре. Мне очень понравилось вот это, потому повторяться в этой статье я не буду. Под катом расскажу подробнее почему библиотека работает быстро и о том, как было сделано демо.


      Почему библиотека работает быстро?


      "Как-то не верится что так быстро. Ты точно ниче не считаешь предварительно?"
      Реакция друга, который первый раз увидел библиотеку.

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


      Статистика


      Для замера производительности я взял граф дорог из Нью-Йорка ( ~730 000 ребер, 260 000 узлов). Таблица ниже показывает статистику времени, необходимого для решения одной задачи поиска пути из 250 случайно выбранных:


      Среднее Медиана Min Max p90 p99
      A* ленивый (локальный) 32ms 24ms 0ms 179ms 73ms 136ms
      NBA* 44ms 34ms 0ms 222ms 107ms 172ms
      A*, однонаправленный 55ms 38ms 0ms 356ms 123ms 287ms
      Дейкстра 264ms 258ms 0ms 782ms 483ms 631ms

      Каждый алгоритм решал одну и ту же задачу. A* ленивый самый быстрый, но его решение не всегда оптимально. По-сути, это двунаправленный A* который сразу же выходит как только оба поиска встретились. NBA* двунаправленный, сходится к оптимальному решению. В 99% ему понадобилось меньше чем 172 миллисекунды, чтобы найти кратчайший путь (p99).


      Оптимизации


      Библиотека работает относительно быстро по нескольким причинам.


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


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


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


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


      Как работает демо?


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


      Прежде чем начнем. Кто-то меня спросил: "Но ведь это же граф? Как можно карту представить в виде графа?". Легче всего представить каждый перекресток узлом графа. У каждого перекрестка есть позиция (x, y). Каждый прямой участок дороги сделаем ребром графа. Изгибы дороги можно моделировать как частный случай перекрестков.


      Готовим данные


      Конечно, я слышал об https://www.openstreetmap.org, но их внешний вид меня не сильно привлекал. Когда же я обнаружил API и инструменты типа http://overpass-turbo.eu/ — это как новый мир открылся перед глазами :). Данные они отдают под лицензией ODbL, которая требует чтобы их упомянули (чем больше людей знают о сервисе — тем лучше становится сервис).


      API позволяет делать очень сложные запросы, и дает потрясающие объемы информации.


      Например, такой запрос даст все велодороги в Москве:


      [out:json];
      // Сохранить область в переменную `a`
      (area["name"="Москва"])->.a;
      // Скачать все дороги внутри a у которых аттрибут `highway == cycleway`
      way["highway"="cycleway"](area.a);
      
      // и объединить дороги с узлами графа (узлы содержат геопозицию)
      node(w);
      
      // Наконец, вернуть результаты
      out meta;

      API очень хорошо описано здесь: http://wiki.openstreetmap.org/wiki/Overpass_API


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


      Сохраняем граф


      Данные OSM отдает в виде XML или JSON. К сожалению оба форматы слишком объемные — карта Москвы со всеми дорогами занимает около 47MB. Моя же задача была сделать загрузку сайта как можно быстрее (даже на мобильном соединении).


      Можно было бы попробовать сжать gzip'ом — карта Москвы из 47МБ превращается в 7.1МБ. Но при таком подходе у меня не было бы контроля над скоростью распаковки данных — их бы пришлось парсить javascript'ом на клиенте, что тоже повлияло бы на скорость инициализации.


      Я решил написать свой формат для графа. Граф разбивается на два бинарных файла. Один с координатами всех вершин, а второй с описанием всех ребер.


      Файл с координатами — это просто последовательность из x, y пар (int32, 4 байта на координату). Смещение по которому находится пара координат я рассматриваю как иденификатор вершины (nodeId).


      координаты


      Ребра графа превращаются в обычную последовательность пар fromNodeId, toNodeId.


      ребра


      Последовательность на картинке означает, что первый узел ссылается на второй, а второй ссылается на третий, и так далее.


      Общий размер для графа с V узлами и E ребрами можно подсчитать как:


       storage_size = V * 4 * 2 +  # 4 байта на пару координат на узел
                      E * 4 * 2 =  # 4 байта на пару идентификаторов вершин
                      (V + E) * 8  # суммарно, в байтах

      Это не самый эффективный способ сжатия, но его очень легко реализовать и можно очень быстро восстановить начальный граф на клиенте. Типизированные массивы в javascript'e работают быстрее, чем парсинг JSON'a.


      Сначала я хотел добавить также вес ребер, но остановил себя, ибо загрузка на слабом мобильном соединении даже для маленьких графах станет еще медленнее.


      В первую очередь мобильные телефоны


      Когда я писал демо, я думал, что напишу о нем в Твиттер. Твиттер большинство людей читают с мобилок, а потому и демо должно быть в первую очередь рассчитано на мобильные телефоны. Если оно не будет загружаться быстро, или не будет поддерживать touch — пиши пропало.


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


      Я тестировал демо в первую очередь на платформах iPhone и Андроид. Для тестов на Андроиде я нашел самый дешевый телефон и использовал его. Это очень сильно помогло с отладкой производительности и удобства использования на маленьком экране.


      Асинхронность


      Самая медленная часть в демо была начальная загрузка сайта. Код, который инициализировал граф выглядел как-то так:


      for (let i = 0; i < points.length; i += 2) {
          let nodeId = Math.floor(i / 2);
      
          let x = points[i + 0];
          let y = points[i + 1];
      
          // graph это https://github.com/anvaka/ngraph.graph
          graph.addNode(nodeId, { x, y })
      }

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


      Выход? Я знаю, некоторые используют Web Workers. Это прекрасное решение, учитывая что все сейчас многоядерное. Но в моем случае, использование web workers значительно бы продлило время, необходимое для создания демо. Нужно было бы продумать как передавать данные между потоками, как синхронизировать, как сохранить жизнь батарее, как быть когда web workers не доступны и т.д.


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


      С таким решением у браузера появляется возможность постоянно информировать пользователя о том, что происходит внутри:


      прогресс


       Отрисовка


      Теперь, когда у нас загружен граф, нужно показать его на экране. Конечно, использовать SVG для отрисовки миллиона элементов не годится — скорость начнет проседать после первого десятка тысяч. Можно было бы нарезать граф на тайлы, и использовать Leaflet или OpenSeadragon чтоб нарисовать большую картинку.


      Мне же хотелось иметь больше контроля на кодом (и подучить WebGL), поэтому я написал свой WebGL отрисовщик с нуля. Там я использую подход "scene graph". В таком подходе мы строим сцену из иерархии элементов, которые можно нарисовать. Во время отрисовки кадра, мы проходим по графу, и даем возможность каждому узлу накопить трансформации или вывести себя на экран. Если вы знакомы с three.js или даже обычным DOM'ом — подход будет не в новинку.


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


      Батарейка


      батарейка


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


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


      Я до сих пор не нашел способ как думать быстрее, потому я выбрал второй вариант. Решение оказалось по-наивному простым:


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

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


      function frame() {
          requestAnimationFrame(frame); // Планируем следующий кадр
      
          renderScene(); // рисуем текущий кадр.
          // Ничего плохого в этом нет, но батарею мы можем так быстро посадить
      }

      С "консервативным" подходом, мне нужно было вынести requestAnimationFrame() наружу из функции frame():


      let frameToken = 0;
      
      function renderFrame() {
          if (!frameToken) frameToken = requestAnimationFrame(frame);
      }
      
      function frame() {
          frameToken = 0;
          renderScene();
      }

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


      Переменная frameToken помогает избежать повторного вызова requestAnimationFrame между кадрами.


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


      Текст и линии


      WebGL не самый простой в мире API. Особенно сложно в нем работать с текстом и толстыми линиями (у которых ширина больше одного пикселя).


      текст и линии


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


      С другой стороны, из текста мне нужно было нарисовать только пару меток A и B. А из толстых линий — только путь который соединяет две вершины. Задача вполне по силам для DOM'a.


      Как вы помните, наш отрисовщик использует граф сцены. Почему бы не добавить в сцену еще один элемент, задачей которого будет применять текущую трансформацию к… SVG элементу? Этот SVG элемент сделаем прозрачным, и положим его сверху на canvas. Чтобы убрать все события от мышки — ставим ему pointer-events: none;.


      svg сверху


      Получилось очень быстро и сердито.


      Перемещаемся по карте


      Мне хотелось сделать так, чтобы навигация была похожа на типичное поведение карты (как в Google Maps, например).


      У меня уже была написана библиотека навигации для SVG: anvaka/panzoom. Она поддерживала touch и кинетическое затухание (когда карта продолжает двигаться по инерции). Для того чтобы поддерживать WebGL мне пришлось чуть-чуть подправить библиотеку.


      panzoom слушает события от пользователя (mousedown, touchstart, и т.п.), применяет плавные трансформации к матрице преобразования, и потом, вместо того чтобы напрямую работать с SVG, она отдает матрицу "контроллеру". Задача контроллера — применить трансформацию. Контролер может быть для SVG, для DOM или даже мой собственный контроллер, который применяет трансформацию к WebGL сцене.


      Как понять что кликнуто?


      Мы обсудили как загрузить граф, как его нарисовать, и как двигаться по нему. Но как же понять что было нажато, когда пользователь касается графа? Откуда прокладывать путь и куда?


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


      Я использовал квад дерево чтобы проиндексировать точки. После того как дерево создано — скорость поиска ближайшего соседа становится логарифмической.


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


      В частности, я использовал собственную реализацию, библиотека yaqt, потому что она неприхотлива по памяти для моего формата данных. Существуют лучшие альтернативы, с хорошей документацией и сообществом (например, d3-quadtree).


      Ищем путь


      Теперь все части на своих местах. У нас есть граф, мы знаем как его нарисовать, знаем что было на нем нажато. Осталось только найти кратчайший путь:


      // pathfinder  это объект https://github.com/anvaka/ngraph.path
      let path = pathFinder.find(fromId, toId);

      Теперь у нас есть и массив вершин, которые лежат на найденном пути.


      Заключение


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


      Искренне желаю вам добра!
      Андрей.

      Original source: habrahabr.ru (comments, light).

      https://habrahabr.ru/post/338440/


      Метки:  

      Библиотека быстрого поиска путей на графе

      Понедельник, 25 Сентября 2017 г. 07:01 + в цитатник
      anvaka сегодня в 07:01 Разработка

      Библиотека быстрого поиска путей на графе

        Привет, Друзья!


        Я написал библиотеку поисков путей на произвольных графах, и хотел бы поделиться ей с вами: http://github.com/anvaka/ngraph.path


        Пример использования на огромном графе:





        Поиграться с демо можно здесь: https://anvaka.github.io/ngraph.path.demo/


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


        Описание разных вариантов A* уже не раз встречалось на хабре. Мне очень понравилось вот это, потому повторяться в этой статье я не буду. Под катом расскажу подробнее почему библиотека работает быстро и о том, как было сделано демо.


        Почему библиотека работает быстро?


        "Как-то не верится что так быстро. Ты точно ниче не считаешь предварительно?"
        Реакция друга, который первый раз увидел библиотеку.

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


        Статистика


        Для замера производительности я взял граф дорог из Нью-Йорка ( ~730 000 ребер, 260 000 узлов). Таблица ниже показывает статистику времени, необходимого для решения одной задачи поиска пути из 250 случайно выбранных:


        Среднее Медиана Min Max p90 p99
        A* ленивый (локальный) 32ms 24ms 0ms 179ms 73ms 136ms
        NBA* 44ms 34ms 0ms 222ms 107ms 172ms
        A*, однонаправленный 55ms 38ms 0ms 356ms 123ms 287ms
        Дейкстра 264ms 258ms 0ms 782ms 483ms 631ms

        Каждый алгоритм решал одну и ту же задачу. A* ленивый самый быстрый, но его решение не всегда оптимально. По-сути, это двунаправленный A* который сразу же выходит как только оба поиска встретились. NBA* двунаправленный, сходится к оптимальному решению. В 99% ему понадобилось меньше чем 172 миллисекунды, чтобы найти кратчайший путь (p99).


        Оптимизации


        Библиотека работает относительно быстро по нескольким причинам.


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


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


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


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


        Как работает демо?


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


        Прежде чем начнем. Кто-то меня спросил: "Но ведь это же граф? Как можно карту представить в виде графа?". Легче всего представить каждый перекресток узлом графа. У каждого перекрестка есть позиция (x, y). Каждый прямой участок дороги сделаем ребром графа. Изгибы дороги можно моделировать как частный случай перекрестков.


        Готовим данные


        Конечно, я слышал об https://www.openstreetmap.org, но их внешний вид меня не сильно привлекал. Когда же я обнаружил API и инструменты типа http://overpass-turbo.eu/ — это как новый мир открылся перед глазами :). Данные они отдают под лицензией ODbL, которая требует чтобы их упомянули (чем больше людей знают о сервисе — тем лучше становится сервис).


        API позволяет делать очень сложные запросы, и дает потрясающие объемы информации.


        Например, такой запрос даст все велодороги в Москве:


        [out:json];
        // Сохранить область в переменную `a`
        (area["name"="Москва"])->.a;
        // Скачать все дороги внутри a у которых аттрибут `highway == cycleway`
        way["highway"="cycleway"](area.a);
        
        // и объединить дороги с узлами графа (узлы содержат геопозицию)
        node(w);
        
        // Наконец, вернуть результаты
        out meta;

        API очень хорошо описано здесь: http://wiki.openstreetmap.org/wiki/Overpass_API


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


        Сохраняем граф


        Данные OSM отдает в виде XML или JSON. К сожалению оба форматы слишком объемные — карта Москвы со всеми дорогами занимает около 47MB. Моя же задача была сделать загрузку сайта как можно быстрее (даже на мобильном соединении).


        Можно было бы попробовать сжать gzip'ом — карта Москвы из 47МБ превращается в 7.1МБ. Но при таком подходе у меня не было бы контроля над скоростью распаковки данных — их бы пришлось парсить javascript'ом на клиенте, что тоже повлияло бы на скорость инициализации.


        Я решил написать свой формат для графа. Граф разбивается на два бинарных файла. Один с координатами всех вершин, а второй с описанием всех ребер.


        Файл с координатами — это просто последовательность из x, y пар (int32, 4 байта на координату). Смещение по которому находится пара координат я рассматриваю как иденификатор вершины (nodeId).


        координаты


        Ребра графа превращаются в обычную последовательность пар fromNodeId, toNodeId.


        ребра


        Последовательность на картинке означает, что первый узел ссылается на второй, а второй ссылается на третий, и так далее.


        Общий размер для графа с V узлами и E ребрами можно подсчитать как:


         storage_size = V * 4 * 2 +  # 4 байта на пару координат на узел
                        E * 4 * 2 =  # 4 байта на пару идентификаторов вершин
                        (V + E) * 8  # суммарно, в байтах

        Это не самый эффективный способ сжатия, но его очень легко реализовать и можно очень быстро восстановить начальный граф на клиенте. Типизированные массивы в javascript'e работают быстрее, чем парсинг JSON'a.


        Сначала я хотел добавить также вес ребер, но остановил себя, ибо загрузка на слабом мобильном соединении даже для маленьких графах станет еще медленнее.


        В первую очередь мобильные телефоны


        Когда я писал демо, я думал, что напишу о нем в Твиттер. Твиттер большинство людей читают с мобилок, а потому и демо должно быть в первую очередь рассчитано на мобильные телефоны. Если оно не будет загружаться быстро, или не будет поддерживать touch — пиши пропало.


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


        Я тестировал демо в первую очередь на платформах iPhone и Андроид. Для тестов на Андроиде я нашел самый дешевый телефон и использовал его. Это очень сильно помогло с отладкой производительности и удобства использования на маленьком экране.


        Асинхронность


        Самая медленная часть в демо была начальная загрузка сайта. Код, который инициализировал граф выглядел как-то так:


        for (let i = 0; i < points.length; i += 2) {
            let nodeId = Math.floor(i / 2);
        
            let x = points[i + 0];
            let y = points[i + 1];
        
            // graph это https://github.com/anvaka/ngraph.graph
            graph.addNode(nodeId, { x, y })
        }

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


        Выход? Я знаю, некоторые используют Web Workers. Это прекрасное решение, учитывая что все сейчас многоядерное. Но в моем случае, использование web workers значительно бы продлило время, необходимое для создания демо. Нужно было бы продумать как передавать данные между потоками, как синхронизировать, как сохранить жизнь батарее, как быть когда web workers не доступны и т.д.


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


        С таким решением у браузера появляется возможность постоянно информировать пользователя о том, что происходит внутри:


        прогресс


         Отрисовка


        Теперь, когда у нас загружен граф, нужно показать его на экране. Конечно, использовать SVG для отрисовки миллиона элементов не годится — скорость начнет проседать после первого десятка тысяч. Можно было бы нарезать граф на тайлы, и использовать Leaflet или OpenSeadragon чтоб нарисовать большую картинку.


        Мне же хотелось иметь больше контроля на кодом (и подучить WebGL), поэтому я написал свой WebGL отрисовщик с нуля. Там я использую подход "scene graph". В таком подходе мы строим сцену из иерархии элементов, которые можно нарисовать. Во время отрисовки кадра, мы проходим по графу, и даем возможность каждому узлу накопить трансформации или вывести себя на экран. Если вы знакомы с three.js или даже обычным DOM'ом — подход будет не в новинку.


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


        Батарейка


        батарейка


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


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


        Я до сих пор не нашел способ как думать быстрее, потому я выбрал второй вариант. Решение оказалось по-наивному простым:


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

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


        function frame() {
            requestAnimationFrame(frame); // Планируем следующий кадр
        
            renderScene(); // рисуем текущий кадр.
            // Ничего плохого в этом нет, но батарею мы можем так быстро посадить
        }

        С "консервативным" подходом, мне нужно было вынести requestAnimationFrame() наружу из функции frame():


        let frameToken = 0;
        
        function renderFrame() {
            if (!frameToken) frameToken = requestAnimationFrame(frame);
        }
        
        function frame() {
            frameToken = 0;
            renderScene();
        }

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


        Переменная frameToken помогает избежать повторного вызова requestAnimationFrame между кадрами.


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


        Текст и линии


        WebGL не самый простой в мире API. Особенно сложно в нем работать с текстом и толстыми линиями (у которых ширина больше одного пикселя).


        текст и линии


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


        С другой стороны, из текста мне нужно было нарисовать только пару меток A и B. А из толстых линий — только путь который соединяет две вершины. Задача вполне по силам для DOM'a.


        Как вы помните, наш отрисовщик использует граф сцены. Почему бы не добавить в сцену еще один элемент, задачей которого будет применять текущую трансформацию к… SVG элементу? Этот SVG элемент сделаем прозрачным, и положим его сверху на canvas. Чтобы убрать все события от мышки — ставим ему pointer-events: none;.


        svg сверху


        Получилось очень быстро и сердито.


        Перемещаемся по карте


        Мне хотелось сделать так, чтобы навигация была похожа на типичное поведение карты (как в Google Maps, например).


        У меня уже была написана библиотека навигации для SVG: anvaka/panzoom. Она поддерживала touch и кинетическое затухание (когда карта продолжает двигаться по инерции). Для того чтобы поддерживать WebGL мне пришлось чуть-чуть подправить библиотеку.


        panzoom слушает события от пользователя (mousedown, touchstart, и т.п.), применяет плавные трансформации к матрице преобразования, и потом, вместо того чтобы напрямую работать с SVG, она отдает матрицу "контроллеру". Задача контроллера — применить трансформацию. Контролер может быть для SVG, для DOM или даже мой собственный контроллер, который применяет трансформацию к WebGL сцене.


        Как понять что кликнуто?


        Мы обсудили как загрузить граф, как его нарисовать, и как двигаться по нему. Но как же понять что было нажато, когда пользователь касается графа? Откуда прокладывать путь и куда?


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


        Я использовал квад дерево чтобы проиндексировать точки. После того как дерево создано — скорость поиска ближайшего соседа становится логарифмической.


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


        В частности, я использовал собственную реализацию, библиотека yaqt, потому что она неприхотлива по памяти для моего формата данных. Существуют лучшие альтернативы, с хорошей документацией и сообществом (например, d3-quadtree).


        Ищем путь


        Теперь все части на своих местах. У нас есть граф, мы знаем как его нарисовать, знаем что было на нем нажато. Осталось только найти кратчайший путь:


        // pathfinder  это объект https://github.com/anvaka/ngraph.path
        let path = pathFinder.find(fromId, toId);

        Теперь у нас есть и массив вершин, которые лежат на найденном пути.


        Заключение


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


        Искренне желаю вам добра!
        Андрей.

        Original source: habrahabr.ru (comments, light).

        https://habrahabr.ru/post/338440/


        Метки:  

        PHP-Дайджест № 117 – свежие новости, материалы и инструменты (10 – 24 сентября 2017)

        Понедельник, 25 Сентября 2017 г. 04:38 + в цитатник
        pronskiy сегодня в 04:38 Разработка

        PHP-Дайджест № 117 – свежие новости, материалы и инструменты (10 – 24 сентября 2017)



          Свежая подборка со ссылками на новости и материалы. В выпуске: PHP 7.2.0 RC 2, о будущем HHVM, предложения из PHP Internals, подборка чатов по PHP, видео с конференций и митапов, и многое другое.
          Приятного чтения!



          Новости и релизы


          • О будущем HHVM — Не так давно многие проекты отказались от поддержки HHVM. Теперь команда HVVM анонсировала, что в долгосрочной перспективе не планирует стремиться к полной поддержке PHP 7. Вместо этого, ребята из Facebook сосредоточатся на Hack. Тем не менее в ближайшее время планируется исправить проблемы совместимости с популярными инструментами вроде Composer и PHPUnit.
          • PHP 7.2.0 RC 2 — Второй релиз-кандидат доставлен по расписанию. Следующий выпуск ожидается 28 сентября. Об изменениях ветки можно почитать тут и тут. Протестировать с помощью подготовленного Docker-образа.
          • Sylius v1.0.0 — Мажорный релиз популярной е-коммерс платформы на базе Symfony.


          PHP Internals


          • [RFC] RFC Workflow & Voting — Предлагается регламентировать процесс RFC, в частности, при голосованиях повысить порог принятия изменений до 2/3. Также обозначены критерии для тех, кто может голосовать.
          • [RFC] Class Friendship — Вторая попытка реализовать концепцию дружественных классов. Дружественный класс имеет доступ к private и protected полям класса, в котором он объявлен дружественным.
          • [RFC] Fiber — Интересное дополнение генераторов в PHP, которое позволило бы упростить асинхронный код.
          • Pre-draft PipeOp v2 — В Internals обсуждается черновик предложения для pipe-оператора. Оригинальное предложение было раскритиковано из-за использования плейсхолдера $$ и теперь предложен более простой вариант:
            $x = "hello" 
            |> 'strtoupper' 
            |> function($x) { return $x . " world"; }; 
            // $x === "HELLO world"
            


          Инструменты


          • PoweredLocal/vrata — Реализация паттерна для микросервисов API Gateway на основе Lumen.
          • jamesmoss/flywheel — База данных на основе файлов (JSON, YAML, или Markdown) и с билдером запросов.
          • spatie/macroable — Трейт для динамического добавления методов в класс. Подробнее в посте.
          • felixfbecker/php-language-server — PHP-реализация VS Code Language Server Protocol.
          • BetterReflection 2.0.0 — Рефлексия без загрузки классов.
          • tagua-vm/tagua-vm — Экспериментальная виртуальная машина PHP на Rust и LLVM.


          Материалы для обучения




          Аудио и видеоматериалы




          Занимательное



          Спасибо за внимание!

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

          Прислать ссылку
          Быстрый поиск по всем дайджестам
          <- Предыдущий выпуск: PHP-Дайджест № 116

          Original source: habrahabr.ru (comments, light).

          https://habrahabr.ru/post/338636/


          Метки:  

          PHP-Дайджест № 117 – свежие новости, материалы и инструменты (10 – 24 сентября 2017)

          Понедельник, 25 Сентября 2017 г. 04:38 + в цитатник
          pronskiy сегодня в 04:38 Разработка

          PHP-Дайджест № 117 – свежие новости, материалы и инструменты (10 – 24 сентября 2017)



            Свежая подборка со ссылками на новости и материалы. В выпуске: PHP 7.2.0 RC 2, о будущем HHVM, предложения из PHP Internals, подборка чатов по PHP, видео с конференций и митапов, и многое другое.
            Приятного чтения!



            Новости и релизы


            • О будущем HHVM — Не так давно многие проекты отказались от поддержки HHVM. Теперь команда HVVM анонсировала, что в долгосрочной перспективе не планирует стремиться к полной поддержке PHP 7. Вместо этого, ребята из Facebook сосредоточатся на Hack. Тем не менее в ближайшее время планируется исправить проблемы совместимости с популярными инструментами вроде Composer и PHPUnit.
            • PHP 7.2.0 RC 2 — Второй релиз-кандидат доставлен по расписанию. Следующий выпуск ожидается 28 сентября. Об изменениях ветки можно почитать тут и тут. Протестировать с помощью подготовленного Docker-образа.
            • Sylius v1.0.0 — Мажорный релиз популярной е-коммерс платформы на базе Symfony.


            PHP Internals


            • [RFC] RFC Workflow & Voting — Предлагается регламентировать процесс RFC, в частности, при голосованиях повысить порог принятия изменений до 2/3. Также обозначены критерии для тех, кто может голосовать.
            • [RFC] Class Friendship — Вторая попытка реализовать концепцию дружественных классов. Дружественный класс имеет доступ к private и protected полям класса, в котором он объявлен дружественным.
            • [RFC] Fiber — Интересное дополнение генераторов в PHP, которое позволило бы упростить асинхронный код.
            • Pre-draft PipeOp v2 — В Internals обсуждается черновик предложения для pipe-оператора. Оригинальное предложение было раскритиковано из-за использования плейсхолдера $$ и теперь предложен более простой вариант:
              $x = "hello" 
              |> 'strtoupper' 
              |> function($x) { return $x . " world"; }; 
              // $x === "HELLO world"
              


            Инструменты


            • PoweredLocal/vrata — Реализация паттерна для микросервисов API Gateway на основе Lumen.
            • jamesmoss/flywheel — База данных на основе файлов (JSON, YAML, или Markdown) и с билдером запросов.
            • spatie/macroable — Трейт для динамического добавления методов в класс. Подробнее в посте.
            • felixfbecker/php-language-server — PHP-реализация VS Code Language Server Protocol.
            • BetterReflection 2.0.0 — Рефлексия без загрузки классов.
            • tagua-vm/tagua-vm — Экспериментальная виртуальная машина PHP на Rust и LLVM.


            Материалы для обучения




            Аудио и видеоматериалы




            Занимательное



            Спасибо за внимание!

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

            Прислать ссылку
            Быстрый поиск по всем дайджестам
            <- Предыдущий выпуск: PHP-Дайджест № 116

            Original source: habrahabr.ru (comments, light).

            https://habrahabr.ru/post/338636/


            Метки:  

            Пишем для UEFI BIOS в Visual Studio. Часть 3 — русифицируем Front Page

            Понедельник, 25 Сентября 2017 г. 02:00 + в цитатник

            Метки:  

            Пишем для UEFI BIOS в Visual Studio. Часть 3 — русифицируем Front Page

            Понедельник, 25 Сентября 2017 г. 02:00 + в цитатник

            Метки:  

            Дайджест свежих материалов из мира фронтенда за последнюю неделю №281 (18 — 24 сентября 2017)

            Понедельник, 25 Сентября 2017 г. 00:31 + в цитатник

            Сложно ли сделать из мухи слона?

            Воскресенье, 24 Сентября 2017 г. 20:04 + в цитатник
            third112 сегодня в 20:04 Разработка

            Сложно ли сделать из мухи слона?

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


              Сальвадор Дали. Искушение св. Антония. 1946. (Фрагмент).
              Бельгийский Королевский музей изящных искусств (Брюссель).


              Неужели эта задача требует столь сложного решения? Может, это задача ИИ? – Исхожу из определения:
              к ИИ относятся задачи, которые компьютер решает заметно хуже человека.

              (О применении генетических алгоритмов в ИИ см. книгу: Д. Рутковская, М. Пилиньский, Л. Рутковский, Нейронные сети, генетические алгоритмы и нечеткие системы, М.: Горячая линия – Телеком, 2006).

              Однако ларчик открывается довольно просто. Пусть длина каждого из заданных слов $L$. Из словаря существительных выписываем все слова длиной $L$. Число найденных слов обозначим $N$. Эти слова будут метками вершин неориентированного графа. Каждую пару вершин, метки которых отличаются на одну букву, соединяем ребром. Для этого перебираем все пары вершин, сравнивая их метки – число пар $N(N –1)$, число побуквенных сравнений $LN(N –1)$. Далее решаем типовую задачу поиска кратчайшего пути между указанными вершинами графа.

              Словарь существительных взял с CD-ROM к книге Сергея Мельникова, Delphi и Turbo Pascal на занимательных примерах, СПб.: БХВ – Петербург, 2006 (к слову сказать, в этой книге можно найти много остроумных и простых решений подобных, казалось бы, сложных задач со словами):

              В словаре перечислены все имена существительные «Орфографического словаря»
              (106000 слов, 28-е издание, 1990 г.). [...] Набор текста осуществлён в 1996-98 годах игроками команды «Пузляры» (http://puzzle.ezakaz.ru) — Константином Кнопом, Яковом Зайдельманом, Валерием Тимониным, Виктором Кабановым, Дмитрием Филимоненковым.

              Получил:

              Число загруженных слов (число вершин графа): 1501
              Число ребер: 2402
              Решение: (8 слов) муха-мула-кула-кила-килт-киот-клот-клон-слон
              Затрачено времени: 4.59 сек.


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

              А вот некоторые другие метаграммы:

              муха-мура-бура-бора-кора-корн-коан-клан-улан-улар-удар-удав
              мышка-мошка-кошка-корка-горка
              шило-кило-коло-соло-сало-рало-рыло-мыло
              баран-барон-басон-басок-бачок-бочок-борок-порок-порог-ворог-ворот


              Над последним решением программа думала уже 25.21сек. Интересно, что граф оказывается несвязным. Так, например, не удалось найти решения для пешка – ферзь.

              Можно расширить задачу. Пусть программа находит самые длинные цепочки с заданным числом букв, то есть генерирует головоломки. Для решения этой задачи нужно принять длину ребра нашего графа равной единице и вычислить матрицу расстояний между вершинами. Это можно сделать, например, с помощью алгоритма Флойда-Уоршелла. Так, для слов в 11 букв получим:

              Число загруженных слов: 3391
              Число ребер: 223
              Максимальное расстояние: 9
              Пары на максимальном расстоянии: закатывание-запихивание, запихивание-наматывание, обсаживание-отматывание, отматывание-отсиживание
              Затрачено времени: 3821.45 сек.


              Найдем решение для пары запихивание – наматывание:

              Решение: (9 слов) запихивание-запахивание-запаривание-заваривание-заваливание-закаливание-накаливание-накалывание-накатывание-наматывание
              Затрачено времени: 62.12 сек.


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

              При этом все сказанное ни в коей мере не стоит воспринимать как критику указанной статьи с генетическим алгоритмом. Автор любой работы имеет безусловное право исследовать любой алгоритм на любой задаче. И такое исследование приносит свою пользу. В частности, благодаря ему стало возможным сравнение, приведенное в этой заметке.
              Original source: habrahabr.ru (comments, light).

              https://habrahabr.ru/post/338604/


              Метки:  

              Сложно ли сделать из мухи слона?

              Воскресенье, 24 Сентября 2017 г. 20:04 + в цитатник
              third112 сегодня в 20:04 Разработка

              Сложно ли сделать из мухи слона?

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


                Сальвадор Дали. Искушение св. Антония. 1946. (Фрагмент).
                Бельгийский Королевский музей изящных искусств (Брюссель).


                Неужели эта задача требует столь сложного решения? Может, это задача ИИ? – Исхожу из определения:
                к ИИ относятся задачи, которые компьютер решает заметно хуже человека.

                (О применении генетических алгоритмов в ИИ см. книгу: Д. Рутковская, М. Пилиньский, Л. Рутковский, Нейронные сети, генетические алгоритмы и нечеткие системы, М.: Горячая линия – Телеком, 2006).

                Однако ларчик открывается довольно просто. Пусть длина каждого из заданных слов $L$. Из словаря существительных выписываем все слова длиной $L$. Число найденных слов обозначим $N$. Эти слова будут метками вершин неориентированного графа. Каждую пару вершин, метки которых отличаются на одну букву, соединяем ребром. Для этого перебираем все пары вершин, сравнивая их метки – число пар $N(N –1)$, число побуквенных сравнений $LN(N –1)$. Далее решаем типовую задачу поиска кратчайшего пути между указанными вершинами графа.

                Словарь существительных взял с CD-ROM к книге Сергея Мельникова, Delphi и Turbo Pascal на занимательных примерах, СПб.: БХВ – Петербург, 2006 (к слову сказать, в этой книге можно найти много остроумных и простых решений подобных, казалось бы, сложных задач со словами):

                В словаре перечислены все имена существительные «Орфографического словаря»
                (106000 слов, 28-е издание, 1990 г.). [...] Набор текста осуществлён в 1996-98 годах игроками команды «Пузляры» (http://puzzle.ezakaz.ru) — Константином Кнопом, Яковом Зайдельманом, Валерием Тимониным, Виктором Кабановым, Дмитрием Филимоненковым.

                Получил:

                Число загруженных слов (число вершин графа): 1501
                Число ребер: 2402
                Решение: (8 слов) муха-мула-кула-кила-килт-киот-клот-клон-слон
                Затрачено времени: 4.59 сек.


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

                А вот некоторые другие метаграммы:

                муха-мура-бура-бора-кора-корн-коан-клан-улан-улар-удар-удав
                мышка-мошка-кошка-корка-горка
                шило-кило-коло-соло-сало-рало-рыло-мыло
                баран-барон-басон-басок-бачок-бочок-борок-порок-порог-ворог-ворот


                Над последним решением программа думала уже 25.21сек. Интересно, что граф оказывается несвязным. Так, например, не удалось найти решения для пешка – ферзь.

                Можно расширить задачу. Пусть программа находит самые длинные цепочки с заданным числом букв, то есть генерирует головоломки. Для решения этой задачи нужно принять длину ребра нашего графа равной единице и вычислить матрицу расстояний между вершинами. Это можно сделать, например, с помощью алгоритма Флойда-Уоршелла. Так, для слов в 11 букв получим:

                Число загруженных слов: 3391
                Число ребер: 223
                Максимальное расстояние: 9
                Пары на максимальном расстоянии: закатывание-запихивание, запихивание-наматывание, обсаживание-отматывание, отматывание-отсиживание
                Затрачено времени: 3821.45 сек.


                Найдем решение для пары запихивание – наматывание:

                Решение: (9 слов) запихивание-запахивание-запаривание-заваривание-заваливание-закаливание-накаливание-накалывание-накатывание-наматывание
                Затрачено времени: 62.12 сек.


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

                При этом все сказанное ни в коей мере не стоит воспринимать как критику указанной статьи с генетическим алгоритмом. Автор любой работы имеет безусловное право исследовать любой алгоритм на любой задаче. И такое исследование приносит свою пользу. В частности, благодаря ему стало возможным сравнение, приведенное в этой заметке.
                Original source: habrahabr.ru (comments, light).

                https://habrahabr.ru/post/338604/


                Метки:  

                13-я статья об отрицательном опыте в работе с MS SQL Server

                Воскресенье, 24 Сентября 2017 г. 19:49 + в цитатник
                jobgemws сегодня в 19:49 Администрирование

                13-я статья об отрицательном опыте в работе с MS SQL Server

                • Tutorial

                Предисловие


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

                Ошибки


                1. Процентное приращение файлов БД (базы данных)
                  Т к рост файла (будь то данные или журнал транзакций) БД-весьма ресурсоемкая операция, то благими намерениями может показаться выставление этого роста именно в процентных соотношениях. Соглашусь, во многих рекомендациях сказано, что лучше выставлять не процентный, а фиксированный прирост, выраженный в МБ. Однако, не раскрывается почему именно так. Исходя из практики, не рекомендуется устанавливать прирост файла БД выше 1 ГБ, т к MS SQL Server быстрее выделит 2 раза по 1 ГБ, чем сразу 2 ГБ. Также, если выделять меньше 32 МБ (исходя опять же из практики), то рано или поздно сама база данных начинает просто висеть. Отлично, определились, что приращивать файлы БД стоит фиксировано от 32 до 1024 МБ. Но вот почему еще нельзя в процентах указывать прирост файлов БД? Оказывается, что как только файл станет меньше 1 МБ, то СУБД округляет эту величину до 0 МБ и прекращает увеличивать этот файл. В результате возникает простой системы. Чтобы узнать на сколько увеличивать файл, достаточно сделать анализ за сутки-на сколько вырастает каждый из файлов в МБ, и выставить соответствующее число, но в диапазоне от 32 до 1024 МБ. Сбор статистики по росту файлов БД можно получить следующим образом
                2. Очень много внешних ключей на таблицу
                  Вы когда-нибудь пробовали смотреть план при удалении хотя бы одной строки из таблицы, на которую ссылаются чуть ли не сотни других таблиц? Вы удивитесь, сколько там вложенных циклов. И все они-это проверки по внешним ключам. Поэтому если таблицы большие (миллионники), то лучше выключить внешние ключи на таблицу, в которой будут удаляться данные, затем удалить все необходимые и связанные с ними данные, и после этого включить внешние ключи. Аналогичная ситуация и с каскадными обновлениями и удалениями. Если внешних связей очень много (сотни), то даже удаление 1 строки может привести к долгой и очень обширной блокировке.
                3. Много лишних индексов
                  Часто можно встретить в рекомендациях, что при создании внешних ключей, необходимо для них строить индексы, особенно при использовании этих ключей для соединений. Необходимо проверить, что индексы используются, иначе эти лишние индексы будут только тормозить любые операции по модификации данных. Проверить использование индексов можно следующим запросом:
                  Код
                  select DB_NAME(t.database_id)		as [DBName]
                  	 , SCHEMA_NAME(obj.schema_id)	as [SchemaName]
                  	 , OBJECT_NAME(t.object_id)		as [ObjectName]
                  	 , obj.Type						as [ObjectType]
                  	 , obj.Type_Desc				as [ObjectTypeDesc]
                  	 , ind.name						as [IndexName]
                  	 , ind.Type						as IndexType
                  	 , ind.Type_Desc				as IndexTypeDesc
                  	 , ind.Is_Unique				as IndexIsUnique
                  	 , ind.is_primary_key			as IndexIsPK
                  	 , ind.is_unique_constraint		as IndexIsUniqueConstraint
                  	 , t.[Database_ID]
                  	 , t.[Object_ID]
                  	 , t.[Index_ID]
                  	 , t.Last_User_Seek
                  	 , t.Last_User_Scan
                  	 , t.Last_User_Lookup
                  	 , t.Last_System_Seek
                  	 , t.Last_System_Scan
                  	 , t.Last_System_Lookup
                  from sys.dm_db_index_usage_stats as t
                  inner join sys.objects as obj on t.[object_id]=obj.[object_id]
                  inner join sys.indexes as ind on t.[object_id]=ind.[object_id] and t.index_id=ind.index_id
                  where (last_user_seek	is null or last_user_seek		4 and t.[object_id]>0 --исключаются системные БД
                  


                4. Нерациональное использование ресурсов
                  Часто можно встретить в рекомендациях, что необходимо журнал транзакций и файл данных БД выносить на разные носители данных. Если использовать RAID 10 с 4-мя и более SSD-дисками, то нет смысла изоляции файлов друг от друга. Для еще большей скорости, при необходимости БД tempdb можно разместить на диске, который был сформирован из ОЗУ. Также слишком большие объемы ОЗУ, которые предоставляются СУБД, приведут к тому, что последний заполнит всю память неактуальными планами запросов.
                5. Битые резервные копии
                  Как это не банально может звучать, но всегда нужно не просто проверять созданные резервные копии, а также перемещать их на тестовый стенд и восстанавливать. И все это необходимо автоматизировать с последующим уведомлением администраторам как о проблемных, так и об успешных восстановлениях.
                6. Ложная отказоустойчивость
                  Прежде чем делать из двух и более серверов кластер, необходимо убедиться в том, что система хранения данных тоже отказоустойчива, т к при выходе из строя последнего, сведет к нулю всю отказоустойчивость.
                7. Сложная диагностика без простых проверок
                  Если происходит простой системы, то необходимо сначала проверить журналы MS SQL Server, а уже потом копаться более детально, т к зачастую все проблемы записываются именно туда. Не проводить простых проверок-это то же самое, что не померить температуру пациента, а сразу проводить сложную диагностику.
                8. Забытые таблицы
                  Таблицы могут распухнуть ненужными старыми данными, которые либо необходимо архивировать в отдельную БД, либо удалять. Также таблицы могут перестать использоваться. Необходимо об этом помнить.

                Это все 8 отрицательных опытов, с которыми мне приходилось сталкиваться.
                Не повторяйте приведенных выше ошибок.

                Источники:


                » Документация по SQL
                » Автоматизация по сбору данных о росте таблиц и файлов всех баз данных
                Original source: habrahabr.ru (comments, light).

                https://habrahabr.ru/post/338600/


                Метки:  

                13-я статья об отрицательном опыте в работе с MS SQL Server

                Воскресенье, 24 Сентября 2017 г. 19:49 + в цитатник
                jobgemws сегодня в 19:49 Администрирование

                13-я статья об отрицательном опыте в работе с MS SQL Server

                • Tutorial

                Предисловие


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

                Ошибки


                1. Процентное приращение файлов БД (базы данных)
                  Т к рост файла (будь то данные или журнал транзакций) БД-весьма ресурсоемкая операция, то благими намерениями может показаться выставление этого роста именно в процентных соотношениях. Соглашусь, во многих рекомендациях сказано, что лучше выставлять не процентный, а фиксированный прирост, выраженный в МБ. Однако, не раскрывается почему именно так. Исходя из практики, не рекомендуется устанавливать прирост файла БД выше 1 ГБ, т к MS SQL Server быстрее выделит 2 раза по 1 ГБ, чем сразу 2 ГБ. Также, если выделять меньше 32 МБ (исходя опять же из практики), то рано или поздно сама база данных начинает просто висеть. Отлично, определились, что приращивать файлы БД стоит фиксировано от 32 до 1024 МБ. Но вот почему еще нельзя в процентах указывать прирост файлов БД? Оказывается, что как только файл станет меньше 1 МБ, то СУБД округляет эту величину до 0 МБ и прекращает увеличивать этот файл. В результате возникает простой системы. Чтобы узнать на сколько увеличивать файл, достаточно сделать анализ за сутки-на сколько вырастает каждый из файлов в МБ, и выставить соответствующее число, но в диапазоне от 32 до 1024 МБ. Сбор статистики по росту файлов БД можно получить следующим образом
                2. Очень много внешних ключей на таблицу
                  Вы когда-нибудь пробовали смотреть план при удалении хотя бы одной строки из таблицы, на которую ссылаются чуть ли не сотни других таблиц? Вы удивитесь, сколько там вложенных циклов. И все они-это проверки по внешним ключам. Поэтому если таблицы большие (миллионники), то лучше выключить внешние ключи на таблицу, в которой будут удаляться данные, затем удалить все необходимые и связанные с ними данные, и после этого включить внешние ключи. Аналогичная ситуация и с каскадными обновлениями и удалениями. Если внешних связей очень много (сотни), то даже удаление 1 строки может привести к долгой и очень обширной блокировке.
                3. Много лишних индексов
                  Часто можно встретить в рекомендациях, что при создании внешних ключей, необходимо для них строить индексы, особенно при использовании этих ключей для соединений. Необходимо проверить, что индексы используются, иначе эти лишние индексы будут только тормозить любые операции по модификации данных. Проверить использование индексов можно следующим запросом:
                  Код
                  select DB_NAME(t.database_id)		as [DBName]
                  	 , SCHEMA_NAME(obj.schema_id)	as [SchemaName]
                  	 , OBJECT_NAME(t.object_id)		as [ObjectName]
                  	 , obj.Type						as [ObjectType]
                  	 , obj.Type_Desc				as [ObjectTypeDesc]
                  	 , ind.name						as [IndexName]
                  	 , ind.Type						as IndexType
                  	 , ind.Type_Desc				as IndexTypeDesc
                  	 , ind.Is_Unique				as IndexIsUnique
                  	 , ind.is_primary_key			as IndexIsPK
                  	 , ind.is_unique_constraint		as IndexIsUniqueConstraint
                  	 , t.[Database_ID]
                  	 , t.[Object_ID]
                  	 , t.[Index_ID]
                  	 , t.Last_User_Seek
                  	 , t.Last_User_Scan
                  	 , t.Last_User_Lookup
                  	 , t.Last_System_Seek
                  	 , t.Last_System_Scan
                  	 , t.Last_System_Lookup
                  from sys.dm_db_index_usage_stats as t
                  inner join sys.objects as obj on t.[object_id]=obj.[object_id]
                  inner join sys.indexes as ind on t.[object_id]=ind.[object_id] and t.index_id=ind.index_id
                  where (last_user_seek	is null or last_user_seek		4 and t.[object_id]>0 --исключаются системные БД
                  


                4. Нерациональное использование ресурсов
                  Часто можно встретить в рекомендациях, что необходимо журнал транзакций и файл данных БД выносить на разные носители данных. Если использовать RAID 10 с 4-мя и более SSD-дисками, то нет смысла изоляции файлов друг от друга. Для еще большей скорости, при необходимости БД tempdb можно разместить на диске, который был сформирован из ОЗУ. Также слишком большие объемы ОЗУ, которые предоставляются СУБД, приведут к тому, что последний заполнит всю память неактуальными планами запросов.
                5. Битые резервные копии
                  Как это не банально может звучать, но всегда нужно не просто проверять созданные резервные копии, а также перемещать их на тестовый стенд и восстанавливать. И все это необходимо автоматизировать с последующим уведомлением администраторам как о проблемных, так и об успешных восстановлениях.
                6. Ложная отказоустойчивость
                  Прежде чем делать из двух и более серверов кластер, необходимо убедиться в том, что система хранения данных тоже отказоустойчива, т к при выходе из строя последнего, сведет к нулю всю отказоустойчивость.
                7. Сложная диагностика без простых проверок
                  Если происходит простой системы, то необходимо сначала проверить журналы MS SQL Server, а уже потом копаться более детально, т к зачастую все проблемы записываются именно туда. Не проводить простых проверок-это то же самое, что не померить температуру пациента, а сразу проводить сложную диагностику.
                8. Забытые таблицы
                  Таблицы могут распухнуть ненужными старыми данными, которые либо необходимо архивировать в отдельную БД, либо удалять. Также таблицы могут перестать использоваться. Необходимо об этом помнить.

                Это все 8 отрицательных опытов, с которыми мне приходилось сталкиваться.
                Не повторяйте приведенных выше ошибок.

                Источники:


                » Документация по SQL
                » Автоматизация по сбору данных о росте таблиц и файлов всех баз данных
                Original source: habrahabr.ru (comments, light).

                https://habrahabr.ru/post/338600/


                Метки:  

                Дайджест KolibriOS #13

                Воскресенье, 24 Сентября 2017 г. 18:46 + в цитатник
                Siemargl сегодня в 18:46 Разработка

                Дайджест KolibriOS #13

                  imageМежду выпусками прошло достаточно много времени и накопилось достаточно изменений за 2017г.

                  Список предыдущих выпусков
                  Дайджест KolibriOS #1: ввод в курс дела
                  Дайджест KolibriOS #2: что нам принёс февраль
                  Дайджест KolibriOS #3: начало весны
                  Дайджест KolibriOS #4: и весна нам не помеха
                  Дайджест KolibriOS #5: мы снова с вами
                  Дайджест KolibriOS #6: последняя осень
                  Дайджест KolibriOS #7: как мы зиму перезимовали
                  Дайджест KolibriOS #8: дары весны
                  Дайджест KolibriOS #9: летний урожай
                  Дайджест KolibriOS #10 коротко о накопившемся
                  Дайджест по итогам 2015 года
                  Дайджест KolibriOS #11 все новости с последнего выпуска и Google Summer of Code 2016
                  Дайджест KolibriOS #12




                  Общесистемные изменения (ядро, драйверы, библиотеки)


                  • UNICODE. Очень большое и важное изменение — файловое API SysFn80 теперь полностью поддерживает Юникод (UTF-8, UTF-16LE). Причем поддерживаются все файловые системы — NTFS, FAT, ext2
                  • NTFS. В процессе разработки файловых утилит был сурово протестирован драйвер NTFS, и за исключением некоторых не поддерживаемых функций (шифрование, сжатие, права доступа), работает весьма стабильно
                  • ext2. Исправление найденных ошибок, добавлена поддержка больших файлов >4 GB
                  • C_layer. Библиотека С-интерфейсов для основных системных библиотек доведена до логической Беты
                  • libimg. Поддержка системной библиотекой сохранения в PNG
                  • KF-font. Поддержка шрифтовой библиотеки из Oberon
                  • TCP fixes. Исправление ошибок сетевого стека
                  • Disk subsystem. Поддержка разметки диска GUID Partition Table (GPT)
                  • Memory subsystem. Автоматическая инициализация кучи при первом выделении памяти


                  Средства разработки


                  • GCC. Портирована версия 5.4, в libc добавлена поддержка UNICODE
                  • Tiny C. Добавлена генерация отладочной информации о строках для использования MTDBG
                  • Freebasic. Добавлен тестовый пример использования
                  • Delphi7. Расширяется KolibriOS.lib — библиотека системных вызовов Колибри из D7 и различных ассемблеров (ниже). Добавлены примеры использования (поддерживаются только консольные и Kolibri API приложения)
                  • Ассемблеры. Добавлены примеры вызовов вышеуказанной библиотеки из различных ассемблеров GoAsm, UASM, Tasm
                  • Gentee. Компилятор нового языка программирования портирован на Колибри


                  Изменения в прикладном ПО


                  • NetSurf. Графический браузер дорабатывается, сделан Web-установщик. Смотрите видеоролик на канале в последнем разделе статьи
                  • unzip6 портирован для создания инсталляторов и тестирования ФС
                  • Fb2 reader. Читалка и большая программа, написанная на Oberon под Колибри
                  • VFC. Visual Text Comparer / Diff tool. Программа сравнения файлов. Гифка тут
                  • Clipboard Viewer. Просмотр/очистка системного буфера обмена
                  • Shell. Исправлены мелкие ошибки, увеличена скорость копирования
                  • Kolibri Image Viewer. Системный просмотрщик изображений, добавлено автомасштабирование больших картинок
                  • Файловые утилиты. В процессе тестирования были «подтянуты» и файловые навигаторы Eolite, fNav, KFM


                  Прочее


                  • fillScr Новая утилита рандомной заливки фона рабочего стола.
                  • The Bus Оживлена игрушка
                  • Youtube Playlist Kolibri OS Частный канал видеороликов использования Колибри


                  P.S. Отвечать на комментарии и редактировать не имею возможности ввиду политики Хабра к карма-войнам. Сорри.
                  Original source: habrahabr.ru (comments, light).

                  https://habrahabr.ru/post/338602/


                  Метки:  

                  Дайджест KolibriOS #13

                  Воскресенье, 24 Сентября 2017 г. 18:46 + в цитатник
                  Siemargl сегодня в 18:46 Разработка

                  Дайджест KolibriOS #13

                    imageМежду выпусками прошло достаточно много времени и накопилось достаточно изменений за 2017г.

                    Список предыдущих выпусков
                    Дайджест KolibriOS #1: ввод в курс дела
                    Дайджест KolibriOS #2: что нам принёс февраль
                    Дайджест KolibriOS #3: начало весны
                    Дайджест KolibriOS #4: и весна нам не помеха
                    Дайджест KolibriOS #5: мы снова с вами
                    Дайджест KolibriOS #6: последняя осень
                    Дайджест KolibriOS #7: как мы зиму перезимовали
                    Дайджест KolibriOS #8: дары весны
                    Дайджест KolibriOS #9: летний урожай
                    Дайджест KolibriOS #10 коротко о накопившемся
                    Дайджест по итогам 2015 года
                    Дайджест KolibriOS #11 все новости с последнего выпуска и Google Summer of Code 2016
                    Дайджест KolibriOS #12




                    Общесистемные изменения (ядро, драйверы, библиотеки)


                    • UNICODE. Очень большое и важное изменение — файловое API SysFn80 теперь полностью поддерживает Юникод (UTF-8, UTF-16LE). Причем поддерживаются все файловые системы — NTFS, FAT, ext2
                    • NTFS. В процессе разработки файловых утилит был сурово протестирован драйвер NTFS, и за исключением некоторых не поддерживаемых функций (шифрование, сжатие, права доступа), работает весьма стабильно
                    • ext2. Исправление найденных ошибок, добавлена поддержка больших файлов >4 GB
                    • C_layer. Библиотека С-интерфейсов для основных системных библиотек доведена до логической Беты
                    • libimg. Поддержка системной библиотекой сохранения в PNG
                    • KF-font. Поддержка шрифтовой библиотеки из Oberon
                    • TCP fixes. Исправление ошибок сетевого стека
                    • Disk subsystem. Поддержка разметки диска GUID Partition Table (GPT)
                    • Memory subsystem. Автоматическая инициализация кучи при первом выделении памяти


                    Средства разработки


                    • GCC. Портирована версия 5.4, в libc добавлена поддержка UNICODE
                    • Tiny C. Добавлена генерация отладочной информации о строках для использования MTDBG
                    • Freebasic. Добавлен тестовый пример использования
                    • Delphi7. Расширяется KolibriOS.lib — библиотека системных вызовов Колибри из D7 и различных ассемблеров (ниже). Добавлены примеры использования (поддерживаются только консольные и Kolibri API приложения)
                    • Ассемблеры. Добавлены примеры вызовов вышеуказанной библиотеки из различных ассемблеров GoAsm, UASM, Tasm
                    • Gentee. Компилятор нового языка программирования портирован на Колибри


                    Изменения в прикладном ПО


                    • NetSurf. Графический браузер дорабатывается, сделан Web-установщик. Смотрите видеоролик на канале в последнем разделе статьи
                    • unzip6 портирован для создания инсталляторов и тестирования ФС
                    • Fb2 reader. Читалка и большая программа, написанная на Oberon под Колибри
                    • VFC. Visual Text Comparer / Diff tool. Программа сравнения файлов. Гифка тут
                    • Clipboard Viewer. Просмотр/очистка системного буфера обмена
                    • Shell. Исправлены мелкие ошибки, увеличена скорость копирования
                    • Kolibri Image Viewer. Системный просмотрщик изображений, добавлено автомасштабирование больших картинок
                    • Файловые утилиты. В процессе тестирования были «подтянуты» и файловые навигаторы Eolite, fNav, KFM


                    Прочее


                    • fillScr Новая утилита рандомной заливки фона рабочего стола.
                    • The Bus Оживлена игрушка
                    • Youtube Playlist Kolibri OS Частный канал видеороликов использования Колибри


                    P.S. Отвечать на комментарии и редактировать не имею возможности ввиду политики Хабра к карма-войнам. Сорри.
                    Original source: habrahabr.ru (comments, light).

                    https://habrahabr.ru/post/338602/


                    Метки:  

                    [Перевод] Иллюзия скорости

                    Воскресенье, 24 Сентября 2017 г. 18:02 + в цитатник
                    m1rko сегодня в 18:02 Дизайн

                    Иллюзия скорости

                    • Перевод
                    Много лет я и мои коллеги убеждали разработчиков, что чем быстрее сайт — тем лучше. Статья не о том. Я не собираюсь показывать вам статистику, насколько больше зарабатывают компании, которые оптимизируют сайт для производительности (а это так). Расслабьтесь, возьмите чашечку шоколада — мы вместе совершим путешествие во времени.

                    Настоящее время и воспринимаемое время




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

                    • Время до первого вывода на экран — time to first paint (автоматически)
                    • Время до первого полезного вывода на экран — time to first useful paint (вручную)
                    • Время до первого видового экрана — time to first viewport (полуавтоматически)
                    • Время до появления интерактивности — time to interactive
                    • Загрузка страницы

                    Что вы выберете: измерять абсолютную производительность (загрузка страницы) или воспринимаемую производительность (TTFP, TTUP, TTFV, TTI)? Я проводил исследование, как люди воспринимают движение, и пытался объяснить, почему более высокий fps лучше, чем более низкий — и вскоре стало понятно, что многие вещи, которые я раньше воспринимал чёрно-белыми, на самом деле не являются таковыми. Восприятие движения — невероятно сложная тема, во многом сильно субъективная. Многое из того, что вы думаете, что видите, вы на самом деле… не видите, поскольку оно генерируется в мозге.

                    Как выяснилось, восприятие времени и скорости настолько же искажено, как восприятие движения, если не больше. Как и в моей статье «Иллюзия движения», в качестве введения настоятельно рекомендую великолепную серию статей, которую написал Денис Мишунов для Smashing Mag.

                    Воспринимаемая производительность настолько важна, что даже Apple пишет о ней в своих рекомендациях для разработчиков:

                    «Воспринимаемая производительность во многих случаях настолько же эффективна, как реальная производительность» (Basic Performance Tips)

                    Воспринимаемая реальность — как наш мозг конструирует прошлое, настоящее и будущее


                    То, как мы измеряем воспринимаемое время, кардинально отличается от показаний секундомера. Время — очень абстрактная концепция для людей. Мы не очень хорошо с ней справляемся. Чёрт, мы даже не способны жить в настоящем времени!

                    Настоящее





                    «Мы все живём в прошлом: наше сознание отстаёт на 80 миллисекунд от реальных событий в настоящем. Когда вы думаете, что событие происходит сейчас, оно на самом деле уже произошло», — говорит Дэвид Иглман, нейробиолог. Да, у нашего мозга есть буфер времени!

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

                    К сожалению, буфер времени 80 мс играет с нашим восприятием реальности различные злые шутки. Из журнала Scientific American:



                    Пока хлопальщик ближе 30 метров, вы слышите и видите хлопок одновременно. Но на большем расстоянии разница между скоростью света и скоростью звука превышает 80 миллисекунд, и мозг больше не может синхронизировать изображение со звуком. Самое странное, что переход резкий: буквально делая один шаг назад, хлопальщик выходит из синхронизации. Аналогично, пока саундтрек телепередачи или фильма синхронизирован с видеорядом в пределах 80 миллисекунд, вы не заметите никакого лага, но если задержка будет хоть немного больше, они резко и раздражающе разъединяются. События, которые заканчиваются быстрее чем за 80 миллисекунд, проходят незамеченными для сознания. Бьющий в бейсболе взмахивает битой по мячу прежде чем осознал, что питчер бросил его.

                    В качестве практического примера возьмём торги на бирже. Бизнес, где каждый день тысячи решений принимаются в течение миллисекунд. Поскольку мы не способны ощущать настоящее, то просто не успеваем принимать решения, и вот здесь в игру вступают алгоритмы. Компьютеры не всегда умнее, но они определённо быстрее. Вот почему высокочастотные трейдеры платят $300 млн за частный трансатлантический кабель, чтобы сэкономить 5 миллисекунд.

                    Прошлое и будущее





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

                    И наши воспоминания исключительно субъективны и изменчивы. Вот что говорит Генри Рёдингер, который изучает метапознание:

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

                    Итак, понятно, лучше никогда не думать о заветных воспоминаниях, чтобы они всегда оставались свежими. Что насчёт краткосрочной памяти? Здесь тоже некоторые странности. То, как мы воспринимаем прошедшее время, несколько противоречит интуиции:

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

                    Чтобы понять это, представьте «хранилище памяти» как сжатое хранилище. Мозг сжимает длительные события типа долгой, монотонной поездки, поскольку воспоминания обо всех номерных знаках, которые вы видели по дороге, будут довольно избыточными и бесполезными. Как побочный эффект мы позже воспринимаем прошедшее время короче, чем на самом деле.



                    Абсолютные цели относительного восприятия


                    Итак, мы плохо справляемся с поддержкой равномерного тайминга. В то же время мы всегда пытаемся оперировать объективными цифрами, вроде тех, которые идут из RAIL. Это модель производительности, которую представили разработчики Chrome (потом её заменила PRPL):

                    • цель анимации 60fps
                    • время загрузки 1 секунда
                    • время отклика 100 мс

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

                    • 100-200 мс – мгновенно
                    • < 1 с – немедленно (задержки заметны, но терпимы)
                    • < 5 с – часть потока пользователя
                    • < 12 с – концентрация внимания (attention span)

                    Некоторые из этих показателей вполне надёжные, но выясняется, что это не касается последнего, концентрации внимания: средняя мимолётная концентрация внимания (сфокусированное внимание может продолжаться намного дольше) у людей упало с 12 секунд в 2000 году до 8,25 секунд в 2015-м! Большое спасибо, MTV.

                    Главное — контекст


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

                    Скажем, мы ждём окончания какого-то процесса, здесь простым примером будет загрузка сайта. Как мы узнали ранее, идеальное время загрузки может составлять около 1 секунды. Но, как и во всём предыдущем, тут тоже есть подвох! Контекст имеет большее значение, чем вы думаете:

                    • Вы на автобусной остановке?
                    • На бегу?
                    • В ресторане?
                    • Дома на диване?
                    • На пляже?

                    Не знаю как вы, но я на автобусной остановке никогда не жду окончания загрузки страницы больше 10 секунд. Но если я дома и включил игровую приставку, то я более чем счастлив ожидать минуту загрузки своей игры. Почему? Потому что я уже на своём диване, я уже решил, что буду играть 2-3 часа, так что ROI ожидания в течение 1 минуты более чем сравнимо с веб-страницей статьи, которую я жду 10 секунд ради 20 секунд просмотра.



                    Теперь сконструируем другой пример со временем, на этот раз с 5 секундами. Сравните две ситуации:

                    «Нужно 5 секунд для переключения каналов на ТВ»

                    Вообще медленно!

                    «Этот парень сделал мне буррито за 5 секунд»

                    Но это слишком быстро! Он никак не мог сделать буррито за 5 секунд. Эта штука была готова заранее!

                    Слишком быстро?


                    Погодите. Мы говорим о производительности и заявляем, что нечто может быть слишком быстрым?

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

                    • «Если нечто работает быстро, это должно быть легко»
                    • «Если нечто легко, то оно должно быть дешёвым»

                    Более долгое время ожидания также может создать некое предвкушение и является важным драматическим элементом, особенно при создании — OMG-ощущений от текстового контента. Так когда же ситуация начинает развиваться слишком быстро? Вот несколько примеров:

                    Coinstar


                    Очевидно, машины для автоматического подсчёта монет Coinstar способны делать это гораздо быстрее, чем поверят люди. Поэтому во избежание скептицизма туда добавили искусственную задержку «подсчёта» для правдоподобия (источник).

                    Слесари


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

                    Blogger


                    Из реддит-комментария Карима Майяна:

                    В 2004 году я посетил семинар “Redesigning Blogger”, где Джефф Вин из Adaptive Path и Дуглас Боуман из stopdesign.com (теперь в Twitter) обсуждали редизайн Blogger. Среди их наблюдений — то, что когда пользователи нажимали «Создать блог» на последнем этапе процесса установки, они были смущены тем, насколько быстро создаётся блог. «Это всё? Что-то не так?» — такого рода вопросы они задавали. Поэтому в процесс добавили промежуточный шаг — страницу «Создание блога…», которая ничего не делает, а только показывает маленький вращающийся gif, ожидая несколько секунд, прежде чем перенаправить новых пользователей на страницу «Ура, ваш блог создан!». Более длительным процессом пользователи стали гораздо довольнее.

                    Будем сжимать


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

                    Активное и пассивное ожидание


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

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



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

                    • Оптимистичный UI — Показывать незавершённое действие как завершённое.
                    • Предсказание — Предсказывать исход до его наступления.
                    • Оптическая иллюзия — Иногда даже анимации достаточно для изменения восприятия времени.

                    От теории к практике


                    Упреждающий старт


                    iOS показывает анимацию с приближением во время загрузки приложения, что создаёт впечатление более быстрой загрузки, чем на самом деле, поскольку действие начинается с упреждающием стартом, до того, как приложение готово к показу. Есть ещё предиктивная загрузка: браузер Safari заранее загружает страницы по ссылкам, которые, по его мнению, вы можете нажать (“Top Hits”), и также поступает Top Stories Carousel в Google Search. И если хотите набрать бонусные очки, то можете реализовать на своём сайте многоступенчатый процесс предварительной загрузки: он организован таким образом, что почти всегда можно предсказать следующий шаг, пока пользователь занят чем-то другим. Примеры — формы авторизации, расчёт в интернет-магазине или установка Service Worker.



                    Преждевременное завершение


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



                    Оптимистичный UI


                    Instagram всегда притворяется работающим. Нажатие кнопки Like всегда «работает», даже если вы временно в офлайне. Instagram оптимистично обещает, что совершаемое вами действие случится, рано или поздно.

                    Один совет разработчикам оптимистичных UI: врать хорошо только если вас не словили. Немного оптимистичной лжи может стать проблемой, если вы не сдержите обещание. Если по какой-то причине вы прекратили пользоваться устройством после въезда в тоннель, а позже с другого устройства обнаружите, что никакие из этих лайков не прошли, то почувствуете себя обманутым.

                    Предсказание


                    Кто-то может сказать, что предсказание — это разновидность упреждающего старта, но здесь речь не идёт об активном/пассивном режимах, а скорее об устранении препятствий вроде аппаратных ограничений уже в активной фазе. Отличный пример — метрика под названием glass time, которая описывает задержку между тем, как ваш палец коснётся тачскрина, и получением от экрана визуального фидбека. Даже в самых оптимальных решениях задержка составляет минимум 16-32 мс из-за частоты обновления 60 Гц на большинстве потребительских экранов.

                    Вот почему и Microsoft (начиная с планшетов Surface), и Apple (начиная с iOS 9.1 и Apple Pencil) вложили значительные средства в предсказание нажатий, что является именно тем, что следует из названия: возможностью предсказать будущее положение вашего пальца.

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

                    Оптическая иллюзия


                    Иногда оптические иллюзии — это то, что надо. В мире анимации правильное изменение скорости (easing) может кардинально повлиять на то, как воспринимается анимация:

                    • Ease out (замедление) работает, потому что торможение кажется совершенно естественным, как в реальном мире, а визуальный «вес» переносится на первую половину анимации. На самом деле есть случаи, когда изменение скорости более убедительно и эффективно, чем манипуляция активной/пассивной фазами: инерционная прокрутка (в отличие от традиционной прокрутки) существенно расширяет пассивную фазу, но естественное изменение скорости компенсирует это.
                    • Ease in (ускорение) работает, потому что, как показывают исследования, ваше эмоциональное и восприятие последних моментов более длительного действия определяют то, как вы его запомните. Так что если вы пошли на концерт, и он по большей части был так себе, но последняя песня оказалась восхитительной, у вас будут хорошие воспоминания о концерте. Поэтому для анимированного индикатора выполнения длительного процесса до странности приятно видеть, как он ускоряется ближе к концу, заставляя пользователя думать, что весь процесс прошёл быстрее, чем на самом деле.

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

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

                    Воспринимаемая скорость — ещё не решённое до конца проблемное поле


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

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

                    Никому не интересно, насколько быстрый у вас сайт. Главное, насколько быстрым он кажется.
                    Original source: habrahabr.ru (comments, light).

                    https://habrahabr.ru/post/338598/


                    Метки:  

                    [Перевод] Иллюзия скорости

                    Воскресенье, 24 Сентября 2017 г. 18:02 + в цитатник
                    m1rko сегодня в 18:02 Дизайн

                    Иллюзия скорости

                    • Перевод
                    Много лет я и мои коллеги убеждали разработчиков, что чем быстрее сайт — тем лучше. Статья не о том. Я не собираюсь показывать вам статистику, насколько больше зарабатывают компании, которые оптимизируют сайт для производительности (а это так). Расслабьтесь, возьмите чашечку шоколада — мы вместе совершим путешествие во времени.

                    Настоящее время и воспринимаемое время




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

                    • Время до первого вывода на экран — time to first paint (автоматически)
                    • Время до первого полезного вывода на экран — time to first useful paint (вручную)
                    • Время до первого видового экрана — time to first viewport (полуавтоматически)
                    • Время до появления интерактивности — time to interactive
                    • Загрузка страницы

                    Что вы выберете: измерять абсолютную производительность (загрузка страницы) или воспринимаемую производительность (TTFP, TTUP, TTFV, TTI)? Я проводил исследование, как люди воспринимают движение, и пытался объяснить, почему более высокий fps лучше, чем более низкий — и вскоре стало понятно, что многие вещи, которые я раньше воспринимал чёрно-белыми, на самом деле не являются таковыми. Восприятие движения — невероятно сложная тема, во многом сильно субъективная. Многое из того, что вы думаете, что видите, вы на самом деле… не видите, поскольку оно генерируется в мозге.

                    Как выяснилось, восприятие времени и скорости настолько же искажено, как восприятие движения, если не больше. Как и в моей статье «Иллюзия движения», в качестве введения настоятельно рекомендую великолепную серию статей, которую написал Денис Мишунов для Smashing Mag.

                    Воспринимаемая производительность настолько важна, что даже Apple пишет о ней в своих рекомендациях для разработчиков:

                    «Воспринимаемая производительность во многих случаях настолько же эффективна, как реальная производительность» (Basic Performance Tips)

                    Воспринимаемая реальность — как наш мозг конструирует прошлое, настоящее и будущее


                    То, как мы измеряем воспринимаемое время, кардинально отличается от показаний секундомера. Время — очень абстрактная концепция для людей. Мы не очень хорошо с ней справляемся. Чёрт, мы даже не способны жить в настоящем времени!

                    Настоящее





                    «Мы все живём в прошлом: наше сознание отстаёт на 80 миллисекунд от реальных событий в настоящем. Когда вы думаете, что событие происходит сейчас, оно на самом деле уже произошло», — говорит Дэвид Иглман, нейробиолог. Да, у нашего мозга есть буфер времени!

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

                    К сожалению, буфер времени 80 мс играет с нашим восприятием реальности различные злые шутки. Из журнала Scientific American:



                    Пока хлопальщик ближе 30 метров, вы слышите и видите хлопок одновременно. Но на большем расстоянии разница между скоростью света и скоростью звука превышает 80 миллисекунд, и мозг больше не может синхронизировать изображение со звуком. Самое странное, что переход резкий: буквально делая один шаг назад, хлопальщик выходит из синхронизации. Аналогично, пока саундтрек телепередачи или фильма синхронизирован с видеорядом в пределах 80 миллисекунд, вы не заметите никакого лага, но если задержка будет хоть немного больше, они резко и раздражающе разъединяются. События, которые заканчиваются быстрее чем за 80 миллисекунд, проходят незамеченными для сознания. Бьющий в бейсболе взмахивает битой по мячу прежде чем осознал, что питчер бросил его.

                    В качестве практического примера возьмём торги на бирже. Бизнес, где каждый день тысячи решений принимаются в течение миллисекунд. Поскольку мы не способны ощущать настоящее, то просто не успеваем принимать решения, и вот здесь в игру вступают алгоритмы. Компьютеры не всегда умнее, но они определённо быстрее. Вот почему высокочастотные трейдеры платят $300 млн за частный трансатлантический кабель, чтобы сэкономить 5 миллисекунд.

                    Прошлое и будущее





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

                    И наши воспоминания исключительно субъективны и изменчивы. Вот что говорит Генри Рёдингер, который изучает метапознание:

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

                    Итак, понятно, лучше никогда не думать о заветных воспоминаниях, чтобы они всегда оставались свежими. Что насчёт краткосрочной памяти? Здесь тоже некоторые странности. То, как мы воспринимаем прошедшее время, несколько противоречит интуиции:

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

                    Чтобы понять это, представьте «хранилище памяти» как сжатое хранилище. Мозг сжимает длительные события типа долгой, монотонной поездки, поскольку воспоминания обо всех номерных знаках, которые вы видели по дороге, будут довольно избыточными и бесполезными. Как побочный эффект мы позже воспринимаем прошедшее время короче, чем на самом деле.



                    Абсолютные цели относительного восприятия


                    Итак, мы плохо справляемся с поддержкой равномерного тайминга. В то же время мы всегда пытаемся оперировать объективными цифрами, вроде тех, которые идут из RAIL. Это модель производительности, которую представили разработчики Chrome (потом её заменила PRPL):

                    • цель анимации 60fps
                    • время загрузки 1 секунда
                    • время отклика 100 мс

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

                    • 100-200 мс – мгновенно
                    • < 1 с – немедленно (задержки заметны, но терпимы)
                    • < 5 с – часть потока пользователя
                    • < 12 с – концентрация внимания (attention span)

                    Некоторые из этих показателей вполне надёжные, но выясняется, что это не касается последнего, концентрации внимания: средняя мимолётная концентрация внимания (сфокусированное внимание может продолжаться намного дольше) у людей упало с 12 секунд в 2000 году до 8,25 секунд в 2015-м! Большое спасибо, MTV.

                    Главное — контекст


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

                    Скажем, мы ждём окончания какого-то процесса, здесь простым примером будет загрузка сайта. Как мы узнали ранее, идеальное время загрузки может составлять около 1 секунды. Но, как и во всём предыдущем, тут тоже есть подвох! Контекст имеет большее значение, чем вы думаете:

                    • Вы на автобусной остановке?
                    • На бегу?
                    • В ресторане?
                    • Дома на диване?
                    • На пляже?

                    Не знаю как вы, но я на автобусной остановке никогда не жду окончания загрузки страницы больше 10 секунд. Но если я дома и включил игровую приставку, то я более чем счастлив ожидать минуту загрузки своей игры. Почему? Потому что я уже на своём диване, я уже решил, что буду играть 2-3 часа, так что ROI ожидания в течение 1 минуты более чем сравнимо с веб-страницей статьи, которую я жду 10 секунд ради 20 секунд просмотра.



                    Теперь сконструируем другой пример со временем, на этот раз с 5 секундами. Сравните две ситуации:

                    «Нужно 5 секунд для переключения каналов на ТВ»

                    Вообще медленно!

                    «Этот парень сделал мне буррито за 5 секунд»

                    Но это слишком быстро! Он никак не мог сделать буррито за 5 секунд. Эта штука была готова заранее!

                    Слишком быстро?


                    Погодите. Мы говорим о производительности и заявляем, что нечто может быть слишком быстрым?

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

                    • «Если нечто работает быстро, это должно быть легко»
                    • «Если нечто легко, то оно должно быть дешёвым»

                    Более долгое время ожидания также может создать некое предвкушение и является важным драматическим элементом, особенно при создании — OMG-ощущений от текстового контента. Так когда же ситуация начинает развиваться слишком быстро? Вот несколько примеров:

                    Coinstar


                    Очевидно, машины для автоматического подсчёта монет Coinstar способны делать это гораздо быстрее, чем поверят люди. Поэтому во избежание скептицизма туда добавили искусственную задержку «подсчёта» для правдоподобия (источник).

                    Слесари


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

                    Blogger


                    Из реддит-комментария Карима Майяна:

                    В 2004 году я посетил семинар “Redesigning Blogger”, где Джефф Вин из Adaptive Path и Дуглас Боуман из stopdesign.com (теперь в Twitter) обсуждали редизайн Blogger. Среди их наблюдений — то, что когда пользователи нажимали «Создать блог» на последнем этапе процесса установки, они были смущены тем, насколько быстро создаётся блог. «Это всё? Что-то не так?» — такого рода вопросы они задавали. Поэтому в процесс добавили промежуточный шаг — страницу «Создание блога…», которая ничего не делает, а только показывает маленький вращающийся gif, ожидая несколько секунд, прежде чем перенаправить новых пользователей на страницу «Ура, ваш блог создан!». Более длительным процессом пользователи стали гораздо довольнее.

                    Будем сжимать


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

                    Активное и пассивное ожидание


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

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



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

                    • Оптимистичный UI — Показывать незавершённое действие как завершённое.
                    • Предсказание — Предсказывать исход до его наступления.
                    • Оптическая иллюзия — Иногда даже анимации достаточно для изменения восприятия времени.

                    От теории к практике


                    Упреждающий старт


                    iOS показывает анимацию с приближением во время загрузки приложения, что создаёт впечатление более быстрой загрузки, чем на самом деле, поскольку действие начинается с упреждающием стартом, до того, как приложение готово к показу. Есть ещё предиктивная загрузка: браузер Safari заранее загружает страницы по ссылкам, которые, по его мнению, вы можете нажать (“Top Hits”), и также поступает Top Stories Carousel в Google Search. И если хотите набрать бонусные очки, то можете реализовать на своём сайте многоступенчатый процесс предварительной загрузки: он организован таким образом, что почти всегда можно предсказать следующий шаг, пока пользователь занят чем-то другим. Примеры — формы авторизации, расчёт в интернет-магазине или установка Service Worker.



                    Преждевременное завершение


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



                    Оптимистичный UI


                    Instagram всегда притворяется работающим. Нажатие кнопки Like всегда «работает», даже если вы временно в офлайне. Instagram оптимистично обещает, что совершаемое вами действие случится, рано или поздно.

                    Один совет разработчикам оптимистичных UI: врать хорошо только если вас не словили. Немного оптимистичной лжи может стать проблемой, если вы не сдержите обещание. Если по какой-то причине вы прекратили пользоваться устройством после въезда в тоннель, а позже с другого устройства обнаружите, что никакие из этих лайков не прошли, то почувствуете себя обманутым.

                    Предсказание


                    Кто-то может сказать, что предсказание — это разновидность упреждающего старта, но здесь речь не идёт об активном/пассивном режимах, а скорее об устранении препятствий вроде аппаратных ограничений уже в активной фазе. Отличный пример — метрика под названием glass time, которая описывает задержку между тем, как ваш палец коснётся тачскрина, и получением от экрана визуального фидбека. Даже в самых оптимальных решениях задержка составляет минимум 16-32 мс из-за частоты обновления 60 Гц на большинстве потребительских экранов.

                    Вот почему и Microsoft (начиная с планшетов Surface), и Apple (начиная с iOS 9.1 и Apple Pencil) вложили значительные средства в предсказание нажатий, что является именно тем, что следует из названия: возможностью предсказать будущее положение вашего пальца.

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

                    Оптическая иллюзия


                    Иногда оптические иллюзии — это то, что надо. В мире анимации правильное изменение скорости (easing) может кардинально повлиять на то, как воспринимается анимация:

                    • Ease out (замедление) работает, потому что торможение кажется совершенно естественным, как в реальном мире, а визуальный «вес» переносится на первую половину анимации. На самом деле есть случаи, когда изменение скорости более убедительно и эффективно, чем манипуляция активной/пассивной фазами: инерционная прокрутка (в отличие от традиционной прокрутки) существенно расширяет пассивную фазу, но естественное изменение скорости компенсирует это.
                    • Ease in (ускорение) работает, потому что, как показывают исследования, ваше эмоциональное и восприятие последних моментов более длительного действия определяют то, как вы его запомните. Так что если вы пошли на концерт, и он по большей части был так себе, но последняя песня оказалась восхитительной, у вас будут хорошие воспоминания о концерте. Поэтому для анимированного индикатора выполнения длительного процесса до странности приятно видеть, как он ускоряется ближе к концу, заставляя пользователя думать, что весь процесс прошёл быстрее, чем на самом деле.

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

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

                    Воспринимаемая скорость — ещё не решённое до конца проблемное поле


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

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

                    Никому не интересно, насколько быстрый у вас сайт. Главное, насколько быстрым он кажется.
                    Original source: habrahabr.ru (comments, light).

                    https://habrahabr.ru/post/338598/


                    Метки:  

                    Скрытый JS-майнинг криптовалюты на сайте: альтернатива рекламе или новая чума

                    Воскресенье, 24 Сентября 2017 г. 16:29 + в цитатник
                    Meklon сегодня в 16:29 Разработка

                    Скрытый JS-майнинг криптовалюты на сайте: альтернатива рекламе или новая чума

                      image
                      Буквально недавно промелькнула новость про Pirate Bay, который начал тестировать криптомайнер на JavaScript как альтернативу традиционной рекламной модели. Теперь же, судя по всему, нас ждет волна интеграции подобных скриптов в каждый мелкий магазинчик по продаже швейных принадлежностей. Только сегодня наткнулся на аналогичный скрипт, встроенный в код сайта zveruga.net — небольшой сети по продаже товаров для животных.


                      Зоомагазин и скрипты


                      Сегодня позвонил отец и сообщил, что у него Kaspersky Total Security ругается на скрипт для майнинга на сайте зоомагазина. И даже успел безуспешно поругаться по этому поводу с девушкой на первой линии поддержки. С предсказуемым результатом "Эээээ… Чего? Скрипты?". Решил ради интереса проверить — вдруг ложная эвристика сработала. Оказалось, что вполне корректно сработало — в коде главной страницы http://www.zveruga.net/ нашлась странная вставка:


                      
                      
                      
                      
                      
                      

                      Кусок скрипта, активирующий майнинг оказался встроенным в блок Яндекс.Метрики. При активированном ghostery активности не проявлял, но стоило его временно отключить, как все ядра процессора немедленно нагружалось расчетами. Молодцы ребята из Mozilla. Теперь многопоточность!)


                      Зачем они жрут мои ресурсы?


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


                      1. Сайт кривой — у них даже HTTPS нет на странице авторизации! Взломали китайские боты и напихали скриптов куда попало.
                      2. Реально решили заработать. Почему бы и не добавить каплю доходов в дополнение к рекламе.
                      3. Админу не хватило на пиво.

                      В целом, мне кажется очень странным подобный способ получения прибыли. Сжирание процессора на 100% — это очень-очень грязный ход. Все же о таком следует предупреждать пользователя, который не ожидает такой подлости от браузера. В Kubuntu Linux тормоза интерфейса не ощущаются, видимо, из-за корректной приоритезации, а в Windows 7 система ощутимо начинает тупить. Немного страшно представить себе ситуацию, когда каждая вкладка начнет поедать системные ресурсы, пытаясь убить всех остальных.


                      Adblock для майнеров


                      В целом, вся эта фигня похожа на смесь очередной волны malware и поиска альтернативной модели заработка. Уже много клавиатур растоптано в сетевых баталиях на тему этичности блокировки рекламы. Вечная проблема столкновения интересов двух сторон — пользователь хочет качественный контент, создатель контента и сервиса хочет окупить свои затраты и немного заработать. И еще рекламные сети сбоку пристроились. С распространением блокировщиков рекламы ситуация становится все напряженнее. Кто-то уходит совсем, кто-то начинает показывать жалобных голодных котиков или переходить на модель платной подписки. Большинство тупо превращаются в сгенерированную копирайтерами за еду скриптами помойку с заголовками в духе Роспотребнадзор обвинил селфи в распространении вшей.
                      Возможность выкинуть на мороз рекламщиков крайне заманчиво выглядит для тех ресурсов, которых традиционно гнобят официальные власти — торрент-трекеры, продавцов неправильного укропа и тому подобные. Но и для обычных посещаемых ресурсов это может стать интересной альтернативой рекламной модели. Основные проблемы заключается в нескольких моментах:


                      1. Деньги капают мизерными крохами с каждого пользователя.
                      2. Вкладка со скриптом и браузер должны быть открыты максимально длительное время, что в принципе не очень характерно для современного варианта прыжков со страницы на страницу.
                      3. Конкуренция за CPU между отдельными онлайн-сервисами. Процессор не резиновый, а каждый норовит выкрутить майнинг на полную мощность, чтобы успеть урвать хоть что-то за короткое время.

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


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

                      Original source: habrahabr.ru (comments, light).

                      https://habrahabr.ru/post/338586/


                      Метки:  

                      Скрытый JS-майнинг криптовалюты на сайте: альтернатива рекламе или новая чума

                      Воскресенье, 24 Сентября 2017 г. 16:29 + в цитатник
                      Meklon сегодня в 16:29 Разработка

                      Скрытый JS-майнинг криптовалюты на сайте: альтернатива рекламе или новая чума

                        image
                        Буквально недавно промелькнула новость про Pirate Bay, который начал тестировать криптомайнер на JavaScript как альтернативу традиционной рекламной модели. Теперь же, судя по всему, нас ждет волна интеграции подобных скриптов в каждый мелкий магазинчик по продаже швейных принадлежностей. Только сегодня наткнулся на аналогичный скрипт, встроенный в код сайта zveruga.net — небольшой сети по продаже товаров для животных.


                        Зоомагазин и скрипты


                        Сегодня позвонил отец и сообщил, что у него Kaspersky Total Security ругается на скрипт для майнинга на сайте зоомагазина. И даже успел безуспешно поругаться по этому поводу с девушкой на первой линии поддержки. С предсказуемым результатом "Эээээ… Чего? Скрипты?". Решил ради интереса проверить — вдруг ложная эвристика сработала. Оказалось, что вполне корректно сработало — в коде главной страницы http://www.zveruga.net/ нашлась странная вставка:


                        
                        
                        
                        
                        
                        

                        Кусок скрипта, активирующий майнинг оказался встроенным в блок Яндекс.Метрики. При активированном ghostery активности не проявлял, но стоило его временно отключить, как все ядра процессора немедленно нагружалось расчетами. Молодцы ребята из Mozilla. Теперь многопоточность!)


                        Зачем они жрут мои ресурсы?


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


                        1. Сайт кривой — у них даже HTTPS нет на странице авторизации! Взломали китайские боты и напихали скриптов куда попало.
                        2. Реально решили заработать. Почему бы и не добавить каплю доходов в дополнение к рекламе.
                        3. Админу не хватило на пиво.

                        В целом, мне кажется очень странным подобный способ получения прибыли. Сжирание процессора на 100% — это очень-очень грязный ход. Все же о таком следует предупреждать пользователя, который не ожидает такой подлости от браузера. В Kubuntu Linux тормоза интерфейса не ощущаются, видимо, из-за корректной приоритезации, а в Windows 7 система ощутимо начинает тупить. Немного страшно представить себе ситуацию, когда каждая вкладка начнет поедать системные ресурсы, пытаясь убить всех остальных.


                        Adblock для майнеров


                        В целом, вся эта фигня похожа на смесь очередной волны malware и поиска альтернативной модели заработка. Уже много клавиатур растоптано в сетевых баталиях на тему этичности блокировки рекламы. Вечная проблема столкновения интересов двух сторон — пользователь хочет качественный контент, создатель контента и сервиса хочет окупить свои затраты и немного заработать. И еще рекламные сети сбоку пристроились. С распространением блокировщиков рекламы ситуация становится все напряженнее. Кто-то уходит совсем, кто-то начинает показывать жалобных голодных котиков или переходить на модель платной подписки. Большинство тупо превращаются в сгенерированную копирайтерами за еду скриптами помойку с заголовками в духе Роспотребнадзор обвинил селфи в распространении вшей.
                        Возможность выкинуть на мороз рекламщиков крайне заманчиво выглядит для тех ресурсов, которых традиционно гнобят официальные власти — торрент-трекеры, продавцов неправильного укропа и тому подобные. Но и для обычных посещаемых ресурсов это может стать интересной альтернативой рекламной модели. Основные проблемы заключается в нескольких моментах:


                        1. Деньги капают мизерными крохами с каждого пользователя.
                        2. Вкладка со скриптом и браузер должны быть открыты максимально длительное время, что в принципе не очень характерно для современного варианта прыжков со страницы на страницу.
                        3. Конкуренция за CPU между отдельными онлайн-сервисами. Процессор не резиновый, а каждый норовит выкрутить майнинг на полную мощность, чтобы успеть урвать хоть что-то за короткое время.

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


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

                        Original source: habrahabr.ru (comments, light).

                        https://habrahabr.ru/post/338586/


                        Метки:  

                        Поиск сообщений в rss_rss_hh_full
                        Страницы: 1824 ... 1545 1544 [1543] 1542 1541 ..
                        .. 1 Календарь