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

Поиск сообщений в 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 ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

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

Участникам чемпионата RAIF стали доступны бизнес-данные «М.Видео»

Вторник, 03 Октября 2017 г. 15:40 + в цитатник


Напоминаем, что уже полным ходом идёт чемпионат «RAIF-Challenge 2017», который финиширует 25 октября. В Чемпионате могут испытать свои силы разработчики в сфере ML/AI и им сочувствующие! На момент старта участникам были доступны две номинации — «AI в страховании» и «AI в банках». С понедельника компания «М.Видео» также предоставила свои исходные бизнес-данные для номинации «AI в ритейле».

Подробности под катом.
Читать дальше ->

https://habrahabr.ru/post/339226/


Метки:  

Итоги второго хакатона по ReactOS: мы переходим на GitHub

Вторник, 03 Октября 2017 г. 13:58 + в цитатник
Привет, Хабр! Сейчас мы расскажем кое-что интересное.



C 14 по 18 августа 2017 года в Кёльне (Германия) проходил второй в истории Хакфест по ReactOS. Хотим в этом посте поделится кратким дайджестом об итогах этого мероприятия и приоткрыть завесу тайны над происходившими там событиями.

First pic coming from #ReactOSHackfest ! Coding hard... #development #opensource pic.twitter.com/HoLr2q3x5W

— ReactOS (@reactos) August 14, 2017


В этот раз в Хакфесте очно участвовало на 2 человека меньше, чем в прошлый раз, что конечно немного грустно. Но это было более чем скомпенсировано тем фактом, что такие разрабочики как Вадим Галянт, Herm`es B'elusca-Ma"ito, David Quintana, принимали участие активное участие в заочном формате, а в тестировании разработок Вадима были задействованы все активные пользователи группы ReactOS в VK. Читать дальше ->

https://habrahabr.ru/post/339218/


[Из песочницы] Кому из айтишников на Руси жить хорошо (а кому будет еще лучше)

Вторник, 03 Октября 2017 г. 13:52 + в цитатник
Похоже, сегодня ИТ-специалисту в России стало легче найти работу. Последние впечатления от российского рынка труда: предложения с уровнем зарплаты существенно выше среднего получают специалисты самых разных профилей и не обязательно высокой квалификации. Более того, похоже, что в кои-то веки ИТ-профессионалы получили возможность выбирать из конкурентных предложений! Кандидаты без специального образования и довольно посредственно, на уровне любителя, разбирающиеся в профильных технологиях, с гордостью публикуют в соцсетях свои новые должности — разработчиков, специалистов по технической поддержке, внедренцев…

К тому же, в прессе все чаще появляются истории о низкоквалифицированных разработчиках, которые тем не менее успешно проходили интервью, и уже в ходе работы наносили огромной финансовый ущерб компании. Так, Uber в 2015 случайно опубликовал паспортные данные своих водителей, а Google в 2010 году понес убытки в $100 млн долларов и проиграл суд компании Oracle за использование без разрешения 11 строк кода. И уже не из жизни гигантов: когда работодатель не понимает, что делает разработчик, а сам сотрудник пользуется этим и завышает как сложность своей работы, так и ее стоимость, а впоследствии и пренебрегает добросовестностью исполнения служебных заданий.

Наш интерес к этим вещам далеко не праздный, ведь для агентства AGIMA ИТ-профессионалы — главный производственный актив. Поэтому HR-отдел агентства попросил наших аналитиков отложить в сторону Google Analytics, сплит-тестирования, карточные сортировки и разобраться в этих вопросах. В ходе эксперимента ни один аналитик и текущий проект компании не пострадали.


Читать дальше ->

https://habrahabr.ru/post/339216/


CIS Benchmarks: лучшие практики и рекомендации по информационной безопасности

Вторник, 03 Октября 2017 г. 13:37 + в цитатник

Метки:  

Hacktoberfest Open Hack Day в Avito — анонс

Вторник, 03 Октября 2017 г. 13:10 + в цитатник

Hacktoberfest близко. Как перестать бояться и начать контрибьютить? С кем обсудить самые полезные открытые проекты? Если вы любите опенсорс так же, как и мы, то приходите в гости в наш московский офис 7 октября. Будет кодовикторина, общение с нашими ведущими разработчиками, много опенсорса, свободный микрофон для рассказов о проектах и Hack Time в отличной компании. Под катом — подробности про мероприятие и темы, которые мы обсудим.


Happy Hacktoberfest!

Читать дальше ->

https://habrahabr.ru/post/339198/


Метки:  

[Перевод] Node.js и переход с PHP на JavaScript

Вторник, 03 Октября 2017 г. 12:02 + в цитатник
Больше десяти лет я был PHP-разработчиком, но недавно перешёл на JavaScript, используя его серверные и клиентские возможности. До этого я уже был знаком с JS. Сначала работал с jQuery, потом освоил Angular, и, наконец, начал пользоваться React.

Когда я начинал писать на PHP, я встраивал его в HTML-файлы. Получался не код, а полный бардак. Поэтому, для того, чтобы привести мои разработки в приличный вид, я начал пользоваться фреймворками, в частности, ZF1 и ZF2. Через некоторое время подход, при использовании которого начинают разработку с API, привёл к тому, что у меня оказался сервер, состоящий из сгенерированных REST API и из нескольких сотен строк моего собственного кода.



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

Сегодня я расскажу, в основном, о своём путешествии с серверной стороны PHP на серверную сторону JS в виде Node.js. Здесь я не буду рассказывать о Webpack, React и о других клиентских технологиях JS.
Читать дальше ->

https://habrahabr.ru/post/339176/


Метки:  

Необразованная молодёжь. Ответ преподавателя-совместителя

Вторник, 03 Октября 2017 г. 11:32 + в цитатник

30 сентября пользователь aleshqqa1337 опубликовал искренний и, в целом, правильный пост Необразованная молодёжь. Я понял, что не могу не ответить. Писал комментарий, писал… И в итоге решил написать пост.


Кратко о себе (это важно): работаю программистом-исследователем в сфере ИБ. Сейчас в крупной российской компании, до этого в двух банках, ещё до этого в небольшой инновационной ИБ компании. Преподаю в МГТУ им.Баумана более 3-х лет… И тоже много что насмотрелся.


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


Дальше читать

https://habrahabr.ru/post/339208/


Метки:  

Интернет-аукционы, API и конкретный пример, как на этом могут заработать сторонние разработчики

Вторник, 03 Октября 2017 г. 11:21 + в цитатник


В чем главная проблема всех ICO? 90% проектов собирают деньги на решение несуществующих проблем. Я серьезно, если вчитаться в многочисленные WP, то создастся впечатление, что каждое из них писалось как «манифест решения главной проблемы вселенной». Но мы-то в курсе, что главный ответ на все – это 42, так что идем дальше. В итоге, у нас остается 10% ICO-проектов, проблематика которых вполне реальна, а у десятой части из них – то есть 1% от всей массы – есть еще и уже действующий бизнес в сфере. На той неделе, листая Bits.Media, я нарвался на такой французский проект, входящий в этот 1% – площадку интернет-аукционов DomRaider (изначально парни специализировались на дропкэтчинге — перехвате и выкупе доменных имен с истекшей регистрацией, но решили расшириться) и, вчитываясь в Whitepaper, понял, что у меня появились некоторые мысли на их счет и ими нужно поделиться в письменном виде.

Итак, мы имеем: проект, ICO которого уже состоялось (необходимая сумма была собрана), так что тут мы рассуждать об эмиссии токенов и дивидендах не будем, как, собственно, и агитацией вложиться рублем. Мы тут люди взрослые, так что обсудим пункты, которые касаются разработки независимой экосистемы вокруг интернет-аукционов как таковых и конкретно вокруг проекта французов в качестве живого примера приложения сил. Да, вы не ослышались, в болоте ICO появился проект с открытой инфраструктурой, который с порога заявляет, что хочет привлекать сторонних разработчиков, сделает API и еще позволит все это монетизировать. Не знаю как вам, а мне хочется верить. А в процессе можно и помечтать об идеальном интернет-аукционе.
Читать дальше ->

https://habrahabr.ru/post/339210/


Онлайн-консультанты: тест-обзор 7 популярных систем. Что вы получите, если откинуть рекламу?

Вторник, 03 Октября 2017 г. 11:04 + в цитатник
Прислушайтесь. На рынке поднят очередной технохайп. Биткоины, майнинг, искусственный интеллект, машинное обучение, нейросети, чат-боты, омниканальность. Умы поглощены технологиями, притом, что у подавляющего большинства российских компаний нет даже нормальной CRM.


О чем это я? Когда ты продажник в компании “Вася Пупкин и Ко”, то чихать ты хотел на высокие технологии, даже если сам работаешь в большой IT-компании. Хочется побольше продать (равно) получить побольше процент (равно) заработать на шикарный отпуск где-нибудь на Бали (в идеале свалить туда в релокацию на какое-то время).

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

https://habrahabr.ru/post/339172/


Лекции по криптографии, блокчейну и вообще

Вторник, 03 Октября 2017 г. 11:04 + в цитатник
image

Привет Хабр! Вчера прошел пилотный выпуск стрима на нашем YouTube канале. Олег Ховайко, технический директор Эмеркоина читал лекцию “Основы криптографии”. Визуально не все было гладко, но мы будем стараться.

Это была первая лекция из цикла, предназначеного для IT-специалистов и преподавателей технических вузов. Цикл пройдет в виде интенсива — каждый день на этой неделе в 18:00 по Москве будет по лекции:
Читать дальше ->

https://habrahabr.ru/post/339204/


Метки:  

[Из песочницы] Разработка первой игры. Впечатления и работа над ошибками. Часть 1

Вторник, 03 Октября 2017 г. 10:25 + в цитатник


Создание первой игры от начала до раннего доступа в Steam. Субъективное мнение о инди разработки собственными силами. Делюсь личным опытом, проблемами с которыми придется встретится. Затрону будущее обновление своей игры в качестве примера работы над ошибками.
Читать дальше ->

https://habrahabr.ru/post/339200/


Метки:  

Next billion users: кто эти люди и как они повлияют на мировую экономику

Вторник, 03 Октября 2017 г. 10:01 + в цитатник
Вот примерно так будут выглядеть эти пользователи:

image

Благодаря инициативе Google и ряда других компаний всё идёт к тому, что Интернет прирастёт примерно на 1 миллиард человек прямо вот уже-уже. Сейчас сетью пользуются 2,8 миллиарда человек из 7 доступных, а будет 3,8.

И эти новые парни тут всё поломают, как мне кажется. Сейчас постараюсь объяснить, почему.
Читать дальше ->

https://habrahabr.ru/post/339194/


Метки:  

[Из песочницы] [CppCon 2017] Herb Sutter: Метапрограммирование и кодогенерация в C++

Понедельник, 02 Октября 2017 г. 22:46 + в цитатник



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

Читать дальше ->

https://habrahabr.ru/post/339186/


[CppCon 2017] Ларс Кнолл: C++ фреймворк Qt: История, Настоящее и Будущее

Понедельник, 02 Октября 2017 г. 21:38 + в цитатник

Содержание цикла обзора выступлений CppCon 2017:



Обзор выступления Ларса Кнолла (Lars Knoll), являющегося техническим директором Qt Company. Не ждите от этого выступления слишком многого. В квадратных скобках курсивом мои примечания.




Читать дальше ->

https://habrahabr.ru/post/339180/


Метки:  

[Перевод] Вышел GitLab 10.0: Авто-DevOps и групповые доски задач

Понедельник, 02 Октября 2017 г. 19:26 + в цитатник

Вышел GitLab 10.0 с Авто-DevOps, групповыми досками задач, новой навигацией и множеством других фич.


КПДВ


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


Читать дальше ->

https://habrahabr.ru/post/339174/


Текстовая трансляция со дня открытых дверей Лаборатории Касперского – Open Day 2017

Понедельник, 02 Октября 2017 г. 18:37 + в цитатник
Kaspersky_Lab сегодня в 18:37 Разработка

Текстовая трансляция со дня открытых дверей Лаборатории Касперского – Open Day 2017

    Всем привет! Сегодня мы ведем текстовую трансляцию со дня открытых дверей Лаборатории Касперского – Open Day 2017.

    Видео-стрим:





    Текстовая трансляция под катом.

    image

    Спикеры выступят с топовыми докладами за 2017 год, расскажут про актуальные киберугрозы, поделятся мыслями об интернете вещей и многом другом. Присоединяйтесь!

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

    https://habrahabr.ru/post/339162/


    Метки:  

    [Из песочницы] t1ha

    Понедельник, 02 Октября 2017 г. 17:35 + в цитатник
    yleo сегодня в 17:35 Разработка

    t1ha

    Чуть менее чем самая быстрая, переносимая, 64-битная хэш-функция, с достойным качеством.
    Да, вжух и в дамки, примерно так. Читаем дальше?


    Вместо Disclaimer

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


    Банальности

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


    Ещё немного занудства

    Для стройности изложения необходимо определить понятия «качества» хэш-функции и остальные требования чуть более детально:


    • Базовое качество: Изменение одного или более произвольных бит в произвольном наборе исходных данных, приводит к изменению каждого бита результата с вероятностью 1/2 .
    • Необратимость (стойкость к восстановлению прообраза): Невозможность получения исходных данных или отдельных битов по результату хеширования.
    • Устойчивость к подбору хэша (стойкость к коллизиям первого рода): Сложность поиска/подбора исходного набора данных с целью получения заданного результата или даже отдельных его битов.
    • Устойчивость к подбору сообщений (стойкость к коллизиям второго рода): Сложность поиска/подбора двух разных наборов данных, которые давали бы одинаковый результат или совпадение отдельных битов.

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


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

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


    Базовый вариант t1ha является (самой) быстрой переносимой хэш-функцией для построения хэш-таблиц и других родственных применений. Поэтому базовый вариант t1ha ориентирован на 64-битные little-endian архитектуры, принимает 64-битное подсаливающее значение (seed) и выдает 64-битный результат, который включает усиление длиной ключа и seed-ом. Стоит отметить, t1ha намеренно сконструирована так, чтобы возвращать 0 при нулевых входных данных (ключ нулевого размера и нулевой seed).


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


    Напротив, для статистических испытаний легко получить прозрачные количественные оценки. При этом есть хорошо зарекомендовавшие себя тестовые пакеты, например SMHasher. Для t1ha результаты просты — все варианты t1ha проходят все тесты без каких-либо замечаний. С другой стороны, не следует считать, что у t1ha есть какие-либо свойства сверх тех, что необходимы для целевого применения (построение хэш-таблиц).


    Читатели наверняка оценили бы тщательный и глубокий анализ качественности и/или стойкости t1ha. Однако, исходя из целевых областей применения t1ha это представляется излишним. Проще говоря, нам была важнее скорость, в том числе для коротких ключей. Поэтому много-раундовое перемешивание не рассматривалось. Представляемый вариант t1ha экономит на спичках тактах и выдает 64-битный результат — практически бессмысленно измерять найденный компромисс иначе как статистически, а эти результаты просто хороши.


    На самом деле

    Мы просто берем пример в statistical prove с коллег из Google ;)




    Бенчмарки


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


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


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


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


    Хэширование коротких ключей (среднее для 1..31 байта).
    Смотрим на правую колонку «Cycles/Hash» (чем меньше значение, тем быстрее):


    Function MiB/Second Cycles/Hash
    t1ha 12228.80 35.55
    FastHash64 5578.06 43.42
    CityHash64 11041.72 51.77
    xxHash64 11123.15 56.17
    MetroHash 11808.92 46.33

    Хэширование длинных ключей (256 Кб).
    Смотрим на среднюю колонку «MiB/Second» (чем больше значение, тем быстрее):


    Function MiB/Second Cycles/Hash
    t1ha 12228.80 35.55
    FarmHash64 12145.36 60.12
    CityHash64 11041.72 51.77
    xxHash64 11123.15 56.17
    Spooky64 11820.20 60.39



    Варианты t1ha


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


    Затем потребовалась максимально быстрый вариант хэш-функции, который давал-бы сравнимый по качеству результат, но был максимально адаптирован на целевую платформу. Например, базовый вариант t1ha работает с little-endian порядком байт, из-за чего на big-endian архитектурах требуется конвертация с неизбежной потерей производительности. Так почему-бы не избавиться от лишних операций на конкретной целевой платформе? Таким же образом было добавлено ещё несколько вариантов:


    • Упрощенный вариант для 32-битных платформ, как little, так и big-endian.
    • Вариант с использованием инструкций AES-NI для процессоров без AVX.
    • Два варианта с использованием инструкций AES-NI с использованием AVX.

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


    • t1ha0() — максимально быстрый вариант для текущего процессора.
    • t1ha1() — базовый переносимый 64-битный вариант t1ha.
    • t1ha2() — переносимый 64-битный вариант с чуть большей заботой о качестве.
    • t1ha3() — быстрый переносимый 128-битный вариант для получения отпечатков.
    • и т.д.

    В этой схеме предполагается, что t1ha0() является диспетчером, который реализует перенаправление в зависимости от платформы и возможностей текущего процессора. Кроме этого, не исключается использование суффиксов «_le» и «_be» для явного выбора между little-endian и big-endian вариантами. Таким образом, под «вывеской» t1ha сейчас находиться несколько хеш-функций и это семейство будет пополняться, в том числе с прицелом на отечественный E2K «Эльбрус».


    Представление о текущем наборе функций и их свойствах можно получить из вывода теста. Стоит лишь отметить, что все функции проходят все тесты SMHasher, а производительность вариантов AES-NI сильно варьируется в зависимости от модели процессора:


    Simple bench for x86 (large keys, 262144 bytes):
                  t1ha1_64le:   47151 ticks,  0.1799 clk/byte,  16.679 Gb/s @3GHz
                  t1ha1_64be:   61602 ticks,  0.2350 clk/byte,  12.766 Gb/s @3GHz
                  t1ha0_32le:   94101 ticks,  0.3590 clk/byte,   8.357 Gb/s @3GHz
                  t1ha0_32be:   99804 ticks,  0.3807 clk/byte,   7.880 Gb/s @3GHz
    
    Simple bench for x86 (small keys, 31 bytes):
                  t1ha1_64le:      39 ticks,  1.2581 clk/byte,   2.385 Gb/s @3GHz
                  t1ha1_64be:      42 ticks,  1.3548 clk/byte,   2.214 Gb/s @3GHz
                  t1ha0_32le:      51 ticks,  1.6452 clk/byte,   1.824 Gb/s @3GHz
                  t1ha0_32be:      54 ticks,  1.7419 clk/byte,   1.722 Gb/s @3GHz
    
    Simple bench for AES-NI (medium keys, 127 bytes):
         t1ha0_ia32aes_noavx:      72 ticks,  0.5669 clk/byte,   5.292 Gb/s @3GHz
           t1ha0_ia32aes_avx:      78 ticks,  0.6142 clk/byte,   4.885 Gb/s @3GHz
          t1ha0_ia32aes_avx2:      78 ticks,  0.6142 clk/byte,   4.885 Gb/s @3GHz
    
    Simple bench for AES-NI (large keys, 262144 bytes):
         t1ha0_ia32aes_noavx:   38607 ticks,  0.1473 clk/byte,  20.370 Gb/s @3GHz
           t1ha0_ia32aes_avx:   38595 ticks,  0.1472 clk/byte,  20.377 Gb/s @3GHz
          t1ha0_ia32aes_avx2:   19881 ticks,  0.0758 clk/byte,  39.557 Gb/s @3GHz



    Немного о внутреннем устройстве

    Если говорить чуть более детально, то t1ha построена по схеме Меркла-Дамгарда (в варианте «wipe-pipe») с упрочнением от размера данных и подсаливающего значения. Внутри основного сжимающего цикла используется 256-битное состояние, с аналогичным размером входного блока. Причем для каждого операнда данных реализуется две точки инъекции с перекрестным опылением. По завершению сжимающего цикла выполняется сжатие 256-битного состояния до 128 бит.


    При выполнении описанных действий используются 64-битные операции, комбинирующие миксеры ARX (Add-Rotate-Xor) и MUX/MRX (Mul-Rotate-Xor). Немаловажно, что все эти вычисления выстроены так, чтобы обеспечить возможность параллельного выполнения большинства операция и плотной укладки u-ops как в конвейер, так и в исполняющие устройства x86_64. За счет этого достигается достаточно хорошее качество при практически предельной скорости хэширования длинных ключей.


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


    Далее, оставшийся хвост данных порциями по 64 бита подмешивается попеременно к половинам 128-битного состояния. В заключении выполняется перемешивание состояния одновременно со сжатием до 64-битного результата. Немаловажной особенностью t1ha здесь является использование миксера на базе широкого умножения (128-битное произведение двух 64-битных множителей). Это позволяет реализовать качественно перемешивание с хорошим лавинным эффектом за меньшее количество операций. Несмотря на то, что широкое умножение относительно дорогая операция, меньшее количество операций позволяет t1ha обрабатывать короткие ключи за рекордно малое количество тактов процессора.


    Следует отметить, что используемый миксер на основе широкого умножения и исключающего ИЛИ не идеален. Несмотря на то, что t1ha проходит все тесты SMHasher, у автора есть представление о последствиях неинъективности. Тем не менее, результирующее качество представляется рационально-достаточным, а в планах развития линейки t1ha уже отражено намерение предоставить чуть более качественный вариант.


    Остальное здесь.


    Спасибо за внимание. Всем добра.

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

    https://habrahabr.ru/post/339160/


    Метки:  

    Методы приближенного поиска ближайших соседей

    Понедельник, 02 Октября 2017 г. 15:44 + в цитатник
    Chetter2 сегодня в 15:44 Разработка

    Методы приближенного поиска ближайших соседей


      Довольно часто программисты и специалисты из области data science сталкиваются с задачей поиска похожих профилей пользователей или подбора схожей музыки. Решения могут сводиться к преобразованию объектов в векторную форму и поиску ближайших.


      Мы тоже столкнулись с необходимостью поиска ближайших соседей в задаче распознавания лиц. Там мы формируем векторные представления лиц при помощи нейросети и ищем ближайшие векторы уже известных людей. Изначально для поиска мы выбрали Annoy, как хорошо известный и проверенный алгоритм, используемый в том числе в Spotify. Но быстро поняли, что с его аппетитами по памяти мы либо не вмещаемся в RAM, либо сильно теряем в точности. Это привело к небольшому исследованию. О результатах которого пойдет речь ниже.


      Чтобы разбавить теорию практикой, в статье будет немного кода, где мы ищем ближайших соседей для слов. Получим их векторные представления, используя популярный word2vec. Этот алгоритм выдает близкие векторы для семантически похожих слов. В word2vec CBOW векторные представления получаются как побочный продукт обучения небольшой нейросети, которая предсказывает слово по его окружению. Любопытно, что с векторами можно проворачивать арифметические операции наподобие king + (woman – man) = queen.


      word embeddings


      Посмотрим, как с этим работать в коде.


      model = gensim.models.KeyedVectors.load_word2vec_format('./GoogleNews-vectors-negative300.bin', binary=True)
      start = time.time()
      pprint.pprint(model.wv.most_similar(positive=['king']))
      print('time:', time.time() - start)
      print('king + (woman - man) = ', model.wv.most_similar(positive=['woman', 'king'], negative=['man'])[0])
      print('Japan + (Moscow - Russia) = ', model.wv.most_similar(positive=['Moscow', 'Japan'], negative=['Russia'])[0])

      Получаем:


          [(u'kings', 0.7138045430183411),
           (u'queen', 0.6510956883430481),
           (u'monarch', 0.6413194537162781),
           (u'crown_prince', 0.6204219460487366),
           (u'prince', 0.6159993410110474),
           (u'sultan', 0.5864823460578918),
           (u'ruler', 0.5797567367553711),
           (u'princes', 0.5646552443504333),
           (u'Prince_Paras', 0.5432944297790527),
           (u'throne', 0.5422105193138123)]
          time: 0.236690998077
          king + (woman - man) =  (u'queen', 0.7118192911148071)
          Japan + (Moscow - Russia) =  (u'Tokyo', 0.8696038722991943)

      В примере выше использовалась библиотека для работы с текстом gensim и word2vec модель (1,5 Гбайт) от Google, которая насчитывает 3 миллиона слов и коротких фраз. В выводе кода видно, что к королю близки королевы, монархи и принцы. Также мы убедились, что арифметика с векторами работает. Однако четверть секунды на один запрос — не очень привлекательно, а ведь в gensim сравнительно хорошая реализация bruteforce-поиска (с подсчетом расстояний до всех известных объектов). Далее мы рассмотрим методы, позволяющие сократить это время в сотни раз лишь с небольшими потерями в точности.


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


      nbrs = NearestNeighbors(algorithm='brute', metric='cosine')
      nbrs.fit(model.wv.syn0norm)
      king_vec = model.wv['king'][np.newaxis, :]
      # замерим скорость поиска сосдей к королю без разделения пространства и заодно выведем результат
      start = time.time()
      idxs = nbrs.kneighbors(king_vec, return_distance=False, n_neighbors=10)[0]
      print('full search time:', time.time() - start)
      print([model.wv.index2word[idx] for idx in idxs])
      
      # выберем 2 случайных вектора и получем коэффициенты задающие плоскость между ними
      vec1_idx = random.randint(0, model.wv.syn0norm.shape[0])
      vec2_idx = random.randint(0, model.wv.syn0norm.shape[0])
      plane = model.wv.syn0norm[vec1_idx] - model.wv.syn0norm[vec2_idx]
      
      # в результате следующего умножения матрица-вектор, мы получим вектор. 
      # Знаки элементов этого вектора указывают с какой стороны разделяющей плоскости оказалось слово
      scalar = model.wv.syn0norm.dot(np.transpose(plane))
      
      # определим с какой стороны плоскости запрос и подготовим бинарную маску для выборки векторов по ту же сторону плоскости
      if king_vec.dot(plane) > 0:
          mask = scalar > 0
      else:
          mask = scalar < 0
      
      print('elements in mask:', mask.sum())
      
      half_nbrs = NearestNeighbors(algorithm='brute', metric='cosine')
      half_nbrs.fit(model.wv.syn0norm[mask])
      half_index2word = list(compress(model.wv.index2word, mask))
      
      start = time.time()
      idxs = half_nbrs.kneighbors(king_vec, return_distance=False, n_neighbors=10)[0]
      print('half search time:', time.time() - start)
      print([half_index2word[idx] for idx in idxs])

      Получаем:


          full search time: 20.3163180351
          [u'king', u'kings', u'queen', u'monarch', u'crown_prince', u'prince', u'sultan', u'ruler', u'princes', u'Prince_Paras']
          elements in mask: 1961204
          half search time: 9.15824007988
          [u'king', u'kings', u'queen', u'monarch', u'crown_prince', u'prince', u'sultan', u'ruler', u'princes', u'Prince_Paras']

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



      1. HNSW


      В 2013 году был опубликован один из лучших алгоритмов поиска ближайших соседей Navigable Small World (NSW). В 2016-м появился его наследник Hierarchical Navigable Small World (HNSW).


      Начнем с родительского алгоритма NSW. Он основан на графе «мир тесен». Эти графы имеют любопытную и полезную нам особенность: пара вершин с большой вероятностью не смежна, но они достижимы за сравнительно небольшое число шагов ($\log{N}$ в среднем). Такие графы встречаются довольно часто. К примеру, нейронные сети мозга, группы в социальных сетях и семантическая сеть WordNet — это графы SW. В нашем случае вершинами являются векторы, а ребра соединяют их с ближайшими. В графе также представлены ребра, соединяющие вершины на большом расстоянии.


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



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


      Псевдокод
      K-NNSearch(object q, integer: m, k)
      1 TreeSet [object] tempRes, candidates, visitedSet, result
      2 for (i<-0; i < m; i++) do:
      3    put random entry point in candidates
      4    tempRes<-null
      5    repeat:
      6       get element c closest from candidates to q
      7       remove c from candidates
      8       //check stop condition:
      9       if c is further than k-th element from result
      10          than break repeat
      11    //update list of candidates:
      12    for every element e from friends of c do:
      13       if e is not in visitedSet than
      14          add e to visitedSet, candidates, tempRes
      15
      16    end repeat
      17    //aggregate the results:
      18    add objects from tempRes to result
      19 end for
      20 return best k elements from result

      index = nmslib.init(space='cosinesimil', method='sw-graph')
      nmslib.addDataPointBatch(index, np.arange(model.wv.syn0.shape[0], dtype=np.int32), model.wv.syn0)
      index.createIndex({}, print_progress=True)
      start = time.time()
      items = nmslib.knnQuery(index, 10, king_vec.tolist())
      print(time.time() - start)
      print([model.wv.index2word[idx] for idx in items])

      Получаем:


          0.000545024871826
          [u'king', u'kings', u'queen', u'monarch', u'crown_prince', u'prince', u'sultan', u'ruler', u'princes', u'royal']

      Рассмотрим развитие описанной выше идеи в алгоритме Hierarchical Navigable Small World (HNSW). Он во многом схож с NSW, однако теперь мы имеем дело с иерархией графов: на нулевом слое представлены все объекты, а по мере увеличения слоя — все меньшая и меньшая их подвыборка. При этом все объекты на слое $n+1$ есть и на слое $n$.



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


      Псевдокод
      SearchAtLayer (object q, Set[object] enterPoints, integer: M, ef, layer)
      1  Set [object] visitedSet
      2  priority_queue [object] candidates (closer - first), result (further - first)
      3  candidates, visitedSet, result <- enterPoints
      7
      4  repeat:
      5     object c =candidates.top()
      6     candidates.pop()
      7     //check stop condition:
      8     if d(c,q)>d(result.top(),q) do:
      9        break
      10    //update list of candidates:
      11    for_each object e from c.friends(layer) do:
      12       if e is not in visitedSet do:
      13          add e to visitedSet
      14          if d(e, q)< d(result.top(),q) or result.size()ef do:
      17                result.pop()
      18 return best k elements from result
      
      K-NNSearch (object query, integer: ef)
      1 Set [object] tempRes, enterPoints=[enterpoint]
      2 for i=maxLayer downto 1 do:
      3    tempRes=SearchAtLayer (query, enterPoints, M, 1, i)
      4    enterPoints =closest elements from tempRes
      5 tempRes=SearchAtLayer (query, enterPoints, M, ef, 0)
      6 return best K of tempRes

      1.1. Pros & Cons


      + Алгоритм просто понять


      + Он показывает state-of-the-art результаты


      + Существует эффективная реализация в библиотеке nmslib


      + Небольшие дополнительные расходы памяти на хранение ребер графа


      – Алгоритм не поддерживает сжатие векторных представлений, которое мы рассмотрим далее


      index = nmslib.init(space='cosinesimil', method='hnsw')
      nmslib.addDataPointBatch(index, np.arange(model.wv.syn0.shape[0], dtype=np.int32), model.wv.syn0)
      index.createIndex({}, print_progress=True)
      start = time.time()
      items = nmslib.knnQuery(index, 10, king_vec.tolist())
      print(time.time() - start)
      print([model.wv.index2word[idx] for idx in items])

      Получаем:


          0.000469923019409
          [u'king', u'kings', u'queen', u'monarch', u'crown_prince', u'prince', u'sultan', u'ruler', u'princes', u'Prince_Paras']

      2. FAISS


      В марте 2017 года Facebook представила свое решение для ANN — библиотеку FAISS. Она объединяет множество методов и алгоритмов. В алгоритме, который мы рассмотрим ниже, расстояния до групп векторов будут приближаться расстоянием до опорной точки рядом с ними. Так мы можем выяснить расстояния от запроса до небольшого количества опорных точек, а затем полным перебором посчитать расстояния до векторов, принадлежащих опорной точке, которая ближе остальных к запросу. Разберем этот алгоритм по частям.


      2.1. ADC — asymmetric distance computation


      Рассмотрим подробнее следующую идею: расстояния до групп векторов можно приблизить расстояниями до опорных точек рядом с ними. Опорные точки делят пространство на области. Для поиска опорных точек в FAISS используется широко известный алгоритм кластеризации k-means, векторам сопоставляются полученные центроиды.


      (0.1, 0.2) -> 1
      (0.5, -0.2) -> 2
      (0.1, 0.1) -> 1
      (0.6, -0.1) -> 2
      

      Векторы коллекции аппроксимируются своими центроидами $y \approx q_c(y)$, где $q_c:\mathbb{R}^d \rightarrow C_1 \subset \mathbb{R}^d$ и $C_1$ — множество центроидов. Тогда расстояние от запроса $x$ до $y$ может быть приближено $d(x, y) \approx d(x, q_c(y))$. Такой способ вычисления дистанции называют асимметричным. Простыми словами: мы разбили пространство на области и сказали, что расстояние от запроса до группы векторов, попавших в одну область, приблизительно равно расстоянию до центроида, образующего эту область.



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


      2.2. IVF — inverted file


      В IVF мы инвертируем присвоение. Теперь центроидам сопоставляются списки векторов.


      1 -> [(0.1, 0.2), (0.1, 0.1)]
      2 -> [(0.5, -0.2), (0.6, -0.1)]
      


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


      2.3. PQ — product quantizer


      Последняя составляющая, которой мы коснемся в статье, называется product quantizer. Она обеспечивает сжатие векторов с потерями и применяется, когда векторные представления не влезают в память. Предположим, что наши векторы имеют размерность 128 и мы хотим кодировать их 64 битами (всего 0,5 бита на компоненту), тогда нам придется заниматься квантованием с количеством центроидов, равным $k=2^{64}$. Это нетривиальная задача $O(iknd)$, которая также требует огромной обучающей выборки.


      Упростим задачу, разбив вектор на $m$ частей $y_1, y_2, ..., y_m \in \mathbb{R}^{d/m}$, и по традиции найдем 256 центроидов для каждой из частей. То есть вектор можно переписать как набор индексов центроидов — например $(134, 20, 244, ..., 12)$, а занимает это хозяйство $m$ байт.


      Такой вид кодирования будем применять к остаточным векторам $r(y) = y - q_c(y)$, $r(y) \approx q_r(r(y))$, и тогда $y \approx q_c(y) + q_r(y - q_c(y))$


      2.4. Поиск


      А теперь соберем все это в одной схеме.



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


      import faiss
      
      index = faiss.index_factory(model.wv.syn0norm.shape[1], 'IVF16384,Flat')
      index.verbose = True
      train = model.wv.syn0norm[np.random.binomial(1, 1./3, size=model.wv.syn0norm.shape[0]).astype(bool)]
      index.train(train)
      index.add(model.wv.syn0norm)
      index.nprobe = 100
      start = time.time()
      distances, items = index.search(king_vec, 10)
      print(time.time() - start)
      print([model.wv.index2word[idx] for idx in items[0]])

      Получаем:


          0.0048999786377
          [u'king', u'kings', u'queen', u'monarch', u'crown_prince', u'prince', u'sultan', u'ruler', u'princes', u'Prince_Paras']

      2.5. Pros & Cons


      + Поддержка сжатия


      + Малые накладные расходы на хранение центроидов


      + Возможность вычислений на GPU*


      – В пять раз медленнее HNSW на CPU


      * Мы не смогли быстро завести GPU-реализацию из коробки и решили не тратить время на это.


      3. ANNOY


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


      3.1. Pros & Cons


      + Алгоритм просто понять


      – Он требует много памяти


      – Проигрывает в скорости работы


      Сравнение алгоритмов


      У каждого из алгоритмов есть набор параметров, будь то максимальное количество друзей для вершины (в NSW, HNSW) или количество центроидов (в FAISS). Эти параметры влияют на объем потребляемой памяти, качество и скорость поиска. Автор Annoy реализовал тесты для группы ANN алгоритмов в репозитории ann-benchmarks на разных параметрах. В них оценивается точность поиска десяти ближайших соседей в датасетах, полученных при помощи алгоритмов GloVe и SIFT.


      GloVe — это еще один способ получить векторные представления слов, он превосходит word2vec по всем показателям при обучении на корпусе одного размера. Датасет составлен из 1,2 миллиона векторных представлений слов, обученных на 2 миллиардах твитов. SIFT — старый алгоритм получения ключевых точек изображения и их векторных представлений, устойчивых к трансформациям. Он использовался для распознавания объектов, и важной частью этого распознавания был поиск похожих векторных представлений. Есть несколько вариаций датасетов, нас интересует SIFT 1M, содержащий миллион векторов.


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


      glove
      sift
      Видно, что HNSW уверенно лидирует. Однако на графиках нет FAISS. Facebook самостоятельно сравнил HNSW и FAISS в разных конфигурациях, результаты приведены в таблице.


      Method search time 1-R@1 index size index build time
      Flat-CPU 9.100 s 1.0000 512 MB 0 s
      nmslib (hnsw) 0.081 s 0.8195 512 + 796 MB 173 s
      IVF16384,Flat 0.538 s 0.8980 512 + 8 MB 240 s
      IVF16384,Flat (Titan X) 0.059 s 0.8145 512 + 8 MB 5 s
      Flat-GPU (Titan X) 0.753 s 0.9935 512 MB 0 s

      В таблице методы FAISS без сжатия, в частности IVF16384,Flat. Значит, используется IVFADC c 16 384 центроидами. Расходы памяти указаны для случая с миллионом векторов размерности 128 в float32. HNSW в пять раз быстрее при вычислениях на CPU, но на хранение ребер графа ($32*2*4*1000000/1024^2 = 244$) требуется больше памяти, чем на центроиды ($16384 * 128 * 4 / 1024^2 = 8$).


      4. Заключение


      Мы рассмотрели ряд алгоритмов, применяемых для быстрого поиска ближайших соседей. Annoy проиграл и по памяти, и по скорости работы, но идея хороша и может помочь в решении смежных задач. Например, удобный для чистки датасета алгоритм поиска аномалий isolation forest очень похож по своей задумке. FAISS — отличное решение при ограничениях по памяти, с ним вполне можно уложить миллиард векторных представлений в 60 Гбайт RAM, используя IVF16384, PQ64. Однако если память не узкое место, то стоит выбрать HNSW.


      P. S. Самыми интересными оказались публикации об алгоритмах в FAISS. Там, к примеру, можно прочесть об оптимизации под GPU, об улучшенном методе квантования (Optimized Product Quantization) и о более хитром способе построении индекса (inverted multi-index).


      P. P. S. Для себя мы выбрали HNSW.


      5. Литература


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

      https://habrahabr.ru/post/338360/


      Метки:  

      [Перевод] Новшества серверного рендеринга в React 16

      Понедельник, 02 Октября 2017 г. 15:21 + в цитатник
      ru_vds сегодня в 15:21 Разработка

      Новшества серверного рендеринга в React 16

      • Перевод
      Вышел React 16! Рассказывая об этом событии, можно упомянуть множество замечательных новостей (вроде архитектуры ядра Fibers), но лично меня больше всего восхищают улучшения серверного рендеринга. Предлагаю подробно всё это разобрать и сравнить с тем, что было раньше. Надеюсь, серверный рендеринг в React 16 понравится вам так же, как он понравился мне.



      Как работает SSR в React 15


      Для начала вспомним, как серверный рендеринг (Server-Side Rendering, SSR) выглядит в React 15. Для выполнения SSR обычно поддерживают сервер, основанный на Node, использующий Express, Hapi или Koa, и вызывают renderToString для преобразования корневого компонента в строку, которую затем записывают в ответ сервера:

      // используем Express
      import { renderToString } from "react-dom/server"
      import MyPage from "./MyPage"
      app.get("/", (req, res) => {
        res.write("");
        res.write("
      ");    res.write(renderToString());  res.write("
      ");  res.end(); });

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

      import { render } from "react-dom"
      import MyPage from "./MyPage"
      render(, document.getElementById("content"));

      Если сделать всё правильно, клиентская система рендеринга может просто использовать HTML, сгенерированный на сервере, не обновляя DOM.

      Как же SSR выглядит в React 16?

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


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

      Если случится так, что вы запустите своё приложение на React 16 и столкнётесь с ошибками, пожалуйста, сообщите о них! Это поможет команде разработчиков.

      Метод render() становится методом hydrate()


      Надо отметить, что переходя с React 15 на React 16, вы, возможно, столкнётесь со следующим предупреждением в браузере.


      Очередное полезное предупреждение React. Метод render() теперь называется hydrate()

      Оказывается, в React 16 теперь есть два разных метода для рендеринга на клиентской стороне. Метод render() для ситуаций, когда рендеринг выполняются полностью на клиенте, и метод hydrate() для случаев, когда рендеринг на клиенте основан на результатах серверного рендеринга. Благодаря обратной совместимости новой версии React, render() будет работать и в том случае, если ему передать то, что пришло с сервера. Однако, эти вызовы следует заменить вызовами hydrate() для того, чтобы система перестала выдавать предупреждения, и для того, чтобы подготовить код к React 17. При таком подходе код, показанный выше, изменился бы так:

      import { hydrate } from "react-dom"
      import MyPage from "./MyPage"
      hydrate(, document.getElementById("content"))


      React 16 может работать с массивами, строками и числами


      В React 15 метод компонента render() должен всегда возвращать единственный элемент React. Однако, в React 16 рендеринг на стороне клиента позволяет компонентам, кроме того, возвращать из метода render() строку, число, или массив элементов. Естественно, это касается и SSR.

      Итак, теперь можно выполнять серверный рендеринг компонентов, который выглядит примерно так:

      class MyArrayComponent extends React.Component {
        render() {
          return [
            
      first element
      ,      
      second element
         ];  } } class MyStringComponent extends React.Component {  render() {    return "hey there";  } } class MyNumberComponent extends React.Component {  render() {    return 2;  } }

      Можно даже передать строку, число или массив компонентов методу API верхнего уровня renderToString:

      res.write(renderToString([
            
      first element
      ,      
      second element
         ])); // Не вполне ясно, зачем так делать, но это работает! res.write(renderToString("hey there")); res.write(renderToString(2));

      Это должно позволить вам избавиться от любых div и span, которые просто добавлялись к вашему дереву компонентов React, что ведёт к общему уменьшению размеров HTML-документов.

      React 16 генерирует более эффективный HTML


      Если говорить об уменьшении размеров HTML-документов, то React 16, кроме того, радикально снижает излишнюю нагрузку, создаваемую SSR при формировании HTML-кода. В React 15 каждый HTML-элемент в SSR-документе имеет атрибут data-reactid, значение которого представляет собой монотонно возрастающие ID, и текстовые узлы иногда окружены комментариями с react-text и ID. Для того, чтобы это увидеть, рассмотрим следующий фрагмент кода:

      renderToString(
        
         This is some server-generated HTML.  
      );

      В React 15 этот фрагмент сгенерирует HTML-код, который выглядит так, как показано ниже (переводы строк добавлены для улучшения читаемости кода):

       This is some  server-generated    HTML.

      В React 16, однако, все ID удалены из разметки, в результате HTML, полученный из такого же фрагмента кода, окажется значительно проще:

       This is some server-generated HTML.

      Такой подход, помимо улучшения читаемости кода, может значительно уменьшить размер HTML-документов. Это просто здорово!

      React 16 поддерживает произвольные атрибуты DOM


      В React 15 система рендеринга DOM была довольно сильно ограничена в плане атрибутов HTML-элементов. Она убирала нестандартные HTML-атрибуты. В React 16, однако, и клиентская, и серверная системы рендеринга теперь пропускают произвольные атрибуты, добавленные к HTML-элементам. Для того, чтобы узнать больше об этом новшестве, почитайте пост Дэна Абрамова в блоге React.

      SSR в React 16 не поддерживает обработчики ошибок и порталы


      В клиентской системе рендеринга React есть две новых возможности, которые, к сожалению, не поддерживаются в SSR. Это — обработчики ошибок (Error Boundaries) и порталы (Portals). Обработчикам ошибок посвящён отличный пост Дэна Абрамова в блоге React. Учитывайте однако, что (по крайней мере сейчас) обработчики не реагируют на серверные ошибки. Для порталов, насколько я знаю, пока даже нет пояснительной статьи, но Portal API требует наличия узла DOM, в результате, на сервере его использовать не удастся.

      React 16 производит менее строгую проверку на стороне клиента


      Когда вы восстанавливаете разметку на клиентской стороне в React 15, вызов ReactDom.render() выполняет посимвольное сравнение с серверной разметкой. Если по какой-либо причине будет обнаружено несовпадение, React выдаёт предупреждение в режиме разработки и заменяет всё дерево разметки, сгенерированной на сервере, на HTML, который был сгенерирован на клиенте.

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

      В целом, это изменение не должно особенно сильно повлиять на конечных пользователей, за исключением одного факта: React 16, при вызове ReactDom.render() / hydrate(), не исправляет несовпадающие HTML-атрибуты, сгенерированные SSR. Эта оптимизация производительности означает, что вам понадобится внимательнее относиться к исправлению несовпадений разметки, приводящих к предупреждениям, которые вы видите в режиме development.

      React 16 не нужно компилировать для улучшения производительности


      В React 15, если вы используете SSR в таком виде, в каком он оказывается сразу после установки, производительность оказывается далеко не оптимальной, даже в режиме production. Это так из-за того, что в React есть множество замечательных предупреждений и подсказок для разработчика. Каждое из этих предупреждений выглядит примерно так:

      if (process.env.NODE_ENV !== "production") {
        // что-то тут проверить и выдать полезное
        // предупреждение для разработчика.
      }

      К сожалению, оказывается, что process.env — это не обычный объект JavaScript, и обращение к нему — операция затратная. В итоге, даже если значение NODE_ENV установлено в production, частая проверка переменной окружения ощутимо замедляет серверный рендеринг.

      Для того, чтобы решить эту проблему в React 15, нужно было бы скомпилировать SSR-код для удаления ссылок на process.env, используя что-то вроде Environment Plugin в Webpack, или плагин transform-inline-environment-variables для Babel. По опыту знаю, что многие не компилируют свой серверный код, что, в результате, значительно ухудшает производительность SSR.

      В React 16 эта проблема решена. Тут имеется лишь один вызов для проверки process.env.NODE_ENV в самом начале кода React 16, в итоге компилировать SSR-код для улучшения производительности больше не нужно. Сразу после установки, без дополнительных манипуляций, мы получаем отличную производительность.

      React 16 отличается более высокой производительностью


      Если продолжить разговор о производительности, можно сказать, что те, кто использовал серверный рендеринг React в продакшне, часто жаловались на то, что большие документы обрабатываются медленно, даже с применением всех рекомендаций по улучшению производительности. Тут хочется отметить, что рекомендуется всегда проверять, чтобы переменная NODE_ENV была установлена в значение production, когда вы используете SSR в продакшне.

      С удовольствием сообщают, что, проведя кое-какие предварительные тесты, я обнаружил значительное увеличение производительности серверного рендеринга React 16 на различных версиях Node:


      Рендеринг на сервере в React 16 быстрее, чем в React 16. Чем ниже столбик — тем результат лучше

      При сравнении с React 16, даже с учётом того, что в React 15 обращения к process.env были устранены благодаря компиляции, наблюдается рост производительности примерно в 2.4 раза в Node 4, в 3 раза — в Node 6, и замечательный рост в 3.8 раза в Node 8.4. Если сравнить React 16 и React 15 без компиляции последнего, результаты на последней версии Node будут просто потрясающими.

      Почему React 16 настолько быстрее, чем React 15? Итак, в React 15 серверные и клиентские подсистемы рендеринга представляли собой, в общих чертах, один и тот же код. Это означает потребность в поддержке виртуального DOM во время серверного рендеринга, даже учитывая то, что этот vDOM отбрасывался как только осуществлялся возврат из вызова renderToString. В результате, на сервере проводилось много ненужной работы.

      В React 16, однако, команда разработчиков переписала серверный рендеринг с нуля, и теперь он совершенно не зависит от vDOM. Это и даёт значительный рост производительности.

      Тут хотелось бы сделать одно предупреждение, касающееся ожидаемого роста производительности реальных проектов после перехода на React 16. Проведённые мной тесты заключались в создании огромного дерева из с одним очень простым рекурсивным компонентом React. Это означает, что мой бенчмарк относится к разряду синтетических и почти наверняка не отражает сценарии реального использования React. Если в ваших компонентах имеется множество сложных методов render, обработка которых занимает много циклов процессора, React 16 ничего не сможет сделать для того, чтобы их ускорить. Поэтому, хотя я и ожидаю увидеть ускорение серверного рендеринга при переходе на React 16, я не жду, скажем, трёхкратного роста производительности в реальных приложениях. По непроверенным данным, при использовании React 16 в реальном проекте, удалось достичь роста производительности примерно в 1.3 раза. Лучший способ понять, как React 16 отразится на производительности вашего приложения — попробовать его самостоятельно.

      React 16 поддерживает потоковую передачу данных


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

      Потоковый рендеринг может уменьшить время до получения первого байта (TTFB, Time To First Byte). Начало документа попадает в браузер ещё до создания продолжения документа. В результате, все ведущие браузеры быстрее приступят к разбору и рендерингу документа.
      Ещё одна отличная вещь, которую может получить от рендеринга в поток — это возможность реагировать на ситуацию, когда сервер выдаёт данные быстрее, чем сеть может их принять. На практике это означает, что если сеть перегружена и не может принимать данные, система рендеринга получит соответствующий сигнал и приостановит обработку данных до тех пор, пока нагрузка на сеть не упадёт. В результате окажется, что сервер будет использовать меньше памяти и сможет быстрее реагировать на события ввода-вывода. И то и другое способно помочь серверу нормально работать в сложных условиях.

      Для того, чтобы организовать потоковый рендеринг, нужно вызвать один из двух новых методов react-dom/server: renderToNodeStream или renderToStaticNodeStream, которые соответствуют методам renderToString и renderToStaticMarkup. Вместо возврата строки эти методы возвращают объект Readable. Такие объекты используются в модели работы с потоками Node для сущностей, генерирующих данные.

      Когда вы получаете поток Readable из методов renderToNodeStream или renderToStaticNodeStream, он находится в режиме приостановки, то есть, рендеринг в этот момент ещё не начинался. Рендеринг начнётся только в том случае, если вызвать read, или, более вероятно, подключить поток Readable с помощью pipe к потоку Writable. Большинство веб-фреймворков Node имеют объект ответа, который унаследован от Writable, поэтому обычно можно просто перенаправить Readable в ответ.

      Скажем, вышеприведённый пример с Express можно было бы переписать для потокового рендеринга следующим образом:

      // используем Express
      import { renderToNodeStream } from "react-dom/server"
      import MyPage from "./MyPage"
      app.get("/", (req, res) => {
        res.write("");
        res.write("
      ");  const stream = renderToNodeStream();  stream.pipe(res, { end: false });  stream.on('end', () => {    res.write("
      ");    res.end();  }); });

      Обратите внимание на то, что когда мы перенаправляем поток в объект ответа, нам необходимо использовать необязательный аргумент { end: false } для того, чтобы сообщить потоку о том, что он не должен автоматически завершать ответ при завершении рендеринга. Это позволяет нам закончить оформление тела HTML-документа, и, как только поток будет полностью записан в ответ, завершить ответ самостоятельно.

      Подводные камни потокового рендеринга


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

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

      https://habrahabr.ru/post/339148/


      Метки:  

      Команда Университета ИТМО вышла в финал Всемирной олимпиады роботов

      Понедельник, 02 Октября 2017 г. 14:06 + в цитатник

      Метки:  

      Поиск сообщений в rss_rss_hh_full
      Страницы: 1824 ... 1555 1554 [1553] 1552 1551 ..
      .. 1 Календарь