image
зрештою, я повинен був до цього прийти. Коли я опублікував статтю «Я написав швидку хеш-таблицю», а потім ще одну — «Я написав ще більш швидку хеш-таблицю». Тепер я завершив роботу над самою швидкою хеш-таблицею. І під цим я розумію, що реалізував самий швидкий пошук порівняно з усіма хеш-таблиць, які мені вдалося знайти. При цьому операції вставки та видалення також працюють дуже швидко (хоча і не швидше конкурентів).
Я використовував хешування за алгоритмом Robin Hood з обмеженням максимальної кількості наборів. Якщо елемент повинен бути на відстані більше Х позицій від своєї ідеальної позиції, то збільшуємо таблицю і сподіваємося, що в цьому випадку кожен елемент зможе бути ближче до своєї бажаної позиції. Схоже, такий підхід дійсно добре працює. Величина Х може бути відносно невелика, що дозволяє реалізувати деякі оптимізації внутрішнього циклу пошуку по хеш-таблиці.
Якщо ви хочете тільки спробувати її в роботі, то можете завантажити звідси. Або прокрутіть вниз до розділу «Вихідний код і використання». Хочете подробиць — читайте далі.
Читати далі →

image
Частини 1 і 2: посилання
У першій частині ми поговорили про різних стратегіях обробки помилок і про те, коли їх рекомендується застосовувати. Зокрема, я розповів, що передумови функцій повинні перевірятися з допомогою налагоджувальних тверджень (debug assertions), тобто тільки в режимі налагодження.
Для перевірки умови бібліотека З надає макрос
assert()
, але тільки якщо не визначено
NDEBUG
. Однак, як і у випадку з багатьма іншими речами, це просте, але іноді неефективне рішення. Головна проблема, з якою я зіткнувся, — глобальність рішення: у вас є твердження або скрізь, або ніде. Погано це тому, що ви не зможете вимкнути затвердження в бібліотеці, залишивши їх тільки у власному коді. Тому багато авторів бібліотек самостійно пишуть макроси тверджень, раз за разом.
Читати далі →



Існує дві основні стратегії: обробка виправних помилок (виключення, коди повернення помилково, функції-обробники) і невиправних (
assert()
,
abort()
). В яких випадках яку стратегію краще використовувати?

Читати далі →

Продуктивність старту JavaScript



Веб-розробники знають, як легко розростаються розміри веб-сторінок. Але завантаження сторінки — це не просто передача байтів по дроту. Коли браузер завантажив скрипти, йому потрібно їх отпарсить, інтерпретувати і запустити. У статті ми уважно розглянемо цю фазу і дізнаємося, чому вона може стати причиною уповільнення запуску вашої програми і як це виправити.

Читати далі →

Як працює hashCode() за замовчуванням?


Спроба зазирнути вглиб
hashCode()
призвела до спелеологическому подорожі вихідного коду JVM, з розглядом структури об'єктів і прив'язаною блокування (biased locking), а також дивовижних наслідків для продуктивності, пов'язаних з використанням
hashCode()
за замовчуванням.

Читати далі →

Архітектура микросервисов



На жаль, у мене немає досвіду роботи з микросервисами, але близько року тому я дуже активно цікавився цією темою і вивчив всі джерела інформації, які зміг знайти. Я переглянув кілька виступів на конференціях, прочитав кілька статей дуже авторитетних і досвідчених фахівців на зразок Мартіна Фаулера, Фреда і Джорджа, Едріана Кокрофта та Кріса Річардсона, щоб якомога більше дізнатися про микросервисах. Ця стаття — результат моїх вишукувань.

Читати далі →

Еволюція CSS: від CSS, SASS, BEM і CSS–модулів до styled-components



З самого початку історії інтернету ми потребували стилях для наших сайтів. Багато років нам для цього служив CSS, розвивався в своєму темпі. І тут ми розглянемо історію його розвитку.

Думаю, всі погодяться з таким визначенням: CSS використовується для опису подання документа, написаного на мовою розмітки. Також ні для кого не буде новиною, що за час розвитку CSS став досить потужним засобом і що для використання в команді потрібні додаткові інструменти.

Читати далі →

Підвищуємо продуктивність коду: спочатку думаємо про даних



Займаючись програмуванням рендеринга графіки, ми живемо у світі, в якому обов'язкові низькорівневі оптимізації, щоб домогтися GPU-фреймів завдовжки 30 мс. Для цього ми використовуємо різні методики і розроблені з нуля нові проходи рендеринга з підвищеною продуктивністю (атрибути геометрії, текстурний кеш, експорт і так далі), GPR-стиск, переховування затримки (latency hiding), ROP…

У сфері підвищення продуктивності CPU свого часу застосовувалися різні трюки, і примітно те, що сьогодні вони використовуються для сучасних відеокарт заради прискорення обчислень ALU (Низькорівнева оптимізація для AMD GCN, Швидкий зворотний квадратний корінь в Quake).


Швидкий зворотний квадратний корінь в Quake

Але останнім часом, особливо в світлі переходу на 64 біта, я помітив зростання кількості неоптимизированного коду, немов в індустрії стрімко втрачаються усі накопичені раніше знання. Так, старі трюки на кшталт швидкого зворотного квадратного кореня на сучасних процесорах контрпродуктивні. Але програмісти не повинні забувати про низькорівневих оптимізацію і сподіватися, що компілятори вирішать всі їх проблеми. Не вирішать.

Ця стаття — не вичерпне хардкорное керівництво по залізу. Це всього лише введення, нагадування, звід базових принципів написання ефективного коду для CPU. Я хочу «показати, що низькорівневе мислення сьогодні все ще корисно», навіть якщо мова піде про процесорах, які я міг би додати.

У статті ми розглянемо кешування, векторне програмування, читання і розуміння асемблерного коду, а також написання коду, зручного для компілятора.

Читати далі →

Маловідомі Git-команди



У Git є суворі зобов'язання щодо зворотної сумісності: багато просунуті можливості приховані за різноманітними опціями, а не застосовуються як поведінка за замовчуванням. На щастя, Git також підтримує і аліаси, так що ви можете створювати свої власні команди, які роблять всю характерну для Git магію. Під катом — добірка корисних (або як мінімум забавних) аліасів, визначених у моєму .gitconfig.

Читати далі →

Рев'ю коду в розподіленій команді



Тут описані мої дослідження, як зробити ревізію коду в команді більш приємним заняттям, яке може дати новий досвід всім учасникам. У нас повністю географічно розподілена команда, всі комунікації виконуються через інтернет, і часто асинхронно. Ми використовуємо Trello для опису можливостей продуктів, поодинці створюємо код, відправляємо в GitHub пулл-реквесты, а також користуємося вбудованої в GitHub функцією їх рев'ю. Це відрізняється від перегляду коду лицем до лиця в офісі і навіть за допомогою відеочату.

Якщо не підходити до справи серйозно, то асинхронна і письмова ревізія коду може стати причиною катастрофи в команді, привівши до погіршення взаємодії і співробітництва. Але якщо всі учасники будуть намагатися робити все добре, то такий підхід може працювати дуже ефективно.

Читати далі →