Как стать автором
Обновить

Почему программистам нужно знать структуры данных и как я сэкономил компании $22 000 в год

Время на прочтение1 мин
Количество просмотров22K
Всего голосов 115: ↑4 и ↓111-106
Комментарии59

Комментарии 59

У этих 3х абзацев ещё и черновой вариант был?! Чуствую все таки дождусь когда статьи на хобре в виде твитов появятся.

У этих 3х абзацев еще и tldr есть в телеграм-канале автора

Чуствую все таки дождусь когда статьи на хобре в виде твитов появятся.

Как бы вам помягче рассказать...

А причём тут структуры данных? Если бы я использовал List, то что-то изменилось бы в логике?

Вот видите, знать 2 структуры данных ещё лучше ;)

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

Справедливости ради, проверка contains в List'e может занимать изрядное время. Насколько это критично зависит от количества и качества данных

ПС видимо автор Set таки и не знает, иначе бы не добавлял эту проверку

ПС видимо автор Set таки и не знает, иначе бы не добавлял эту проверку

А почему? Он ведь проверяет наличие uuid в uuids для того, чтобы определить, отправлять ли информацию, или она уже была ранее отправлена, а не для того, чтобы избежать повторного добавления данных в Set.

.contains() для

List: O(min(in-i))

Set: O(1)~

Если я правильно понял, комментарий в постскриптуме не относился к List, а был просто про Set.

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

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

Потому что во многих языках у множеств операция add возвращает boolean, и скорее всего можно было написать вот так:


if uuids.add(uuid) {
    logAnalytics(for: uuid)
}

Ещё бы понять что это вообще за язык, в хабах только Swift указан, но там у множества метода add нету.

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

> Если бы я использовал List, то что-то изменилось бы в логике?
Внутри Set как правило хеш таблица.

А внутри list что?

Что-то другое (массив или связанный список). Хеш таблиц внутри list точно нет.

Если только речь не идёт о PHP

Ну… это скорее исключение, подтверждающее правило. Там же поди строковые ключи, а не целочисленные индексы?

В PHP и структуры данных-то такой нет

Списки в PHP есть: www.php.net/manual/ru/class.spldoublylinkedlist.php, а множества элементарно реализуются через массивы.

Но речь выше была о том, что массив в PHP — достаточно необычный тип данных, одновременно совмещающий в себе и линейный, и ассоциативный массивы.

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

И? Логика то бы не изменилась. Как будет отправляться аналитика один раз так и будет. Цимес в том, что автору помогли не знания структур данных(отличие Set от List), а понимание предметной области и процессов внутри проекта.

Логика нет, а скорость да. Если список большой, может прилично так тормознуть.

И что? Экономия в бабле случилась из-за идеи не отправлять кучу ненужной аналитики, а не от выбора между set и list.

Да.

Видимо приходит много одинаковых событий, и они запихиваются в set, он по определению не хранит в себе одинаковых объектов, таким образом происходит дедупликация.

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

Это смотря в каком языке. В Java, скажем, метод contains использует для сравнения метод объектов - equals. А значит для одинаковых строк(как в примере), List будет работать также как и Set. Просто дольше.

я не согласен с автором, потому чт

наша группа копирайтеров всё ещё вычитывает черновой вариант комментария

говорите тише — Азизбек, Айгуль и Муслимбек еще спят (про часовые пояса не забываем)

Лол. Мы просто пытаемся минимазировать недочёты в постах у друг друга.

P.S.

Спасибо Дархонбеку Маматалиеву и Азизбеку Матчанлву за ревью чернового варианта данного коментария.

Знание структур данных поможет оптимизировать код.

Для начала позволит создать работающий код.
P.S.


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

И сколько же у нас МИЛЛИАРДОВ пользователей?

Не только пользователи страдают от вездесущей, всеятормозящей, трафикожрущей телеметрии.

Одного меня взволновал вопрос, как еще соптимизировали аналитику в самом конце графика?

Сервер уронили )

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

Сразу видно человека который не работал с аналитикой.

Она полностью отображается через 1-2 дня, а сегодняшние значения они в основном лежат на нуле

@ssj100все верно. Аналитика поступает с задержкой

почему именно 22 000 $ , как считали?

Этот момент как раз не вызывает вопросов, если вкратце $22000 - виртуальные попугаи.

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

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

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

К CPU/RAM можно добавить и другие компоненты - жесткий диск, сеть. Тут уж что важно для компании и что можно посчитать.

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

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

Только ногами не пинайте, я не настоящий сварщик, но нельзя ли как-то последовательно пронумеровать элементы на экране числами от 0 и выше? Тогда для хранения информации о том, что аналитика по элементу отправлена, хватило бы битового вектора, где id элемента - это позиция бита в векторе. Думаю, что одного единственно int на экран хватило бы за глаза. Ну и пара битовых операций к нему. Быстрее просто некуда.

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

Так вроде это и сделано, у объектов вычисляются хэши. А что в функции logAnalytics мы не знаем, может там по уиду находится объект и отсылается все состояние.

когда-нибудь он освоит и эту структуру =)

Например если вы видели на экране “XYZ” 10 раз прокрутив контент вверх вниз несколько раз, то аналитика отправлялась 10 раз. Хоть 1 раза было достаточно.

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

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

Чета тут не то...

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

Очень верное замечание. Такими темпами можно вообще аналитику удалить и сэкономить ещё больше непонятно как посчитанных денег.

Ну так, если вы не заметили — эту статью писал один человек, и трое вычитывали. Видимо, одного по итогу сократили, но осталось еще трое. Еще есть куда расти.

-Босс, я придумал как фирме экономить 2 тысячи баксов в месяц!
-Решил уволится?

Не, фикс, наверно полезный для Uber, но памятуя какие у них зарплаты вспоминается этот анекдот.

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

До кучи, писать в такой «лог» чревато потерей информации — представленный фрагмент кода просто отбрасывает ЛЮБЫЕ новые сообщения с тем же идентификатором.

Сто процентов , только хотел написать. Проблема явно в архитетуре , а это попытка замазать проблему. Ну а по поводу статьи , больше самопиар

Справедливости ради, там написано "дедупликация аналитики", а не "дедупликация UUID". Это не одно и тоже.

Да и по логике видно, что идёт проверка на наличие UUID, а не проверка на его уникальность.

Я правильно понял, что в конце графика бэкенд упал с ООМ?

Этот сет по-хорошему должен быть ограниченным по количеству LRU list

Проблема

Часто используемый скрин приложения отправлял impression аналитику при прокрутке экрана с дублированием. Например если вы видели на экране “XYZ” 10 раз прокрутив контент вверх вниз несколько раз, то аналитика отправлялась 10 раз. Хоть 1 раза было достаточно.

А с каких пор для аналитики это стала проблема? мне кажется это автор своим решением сделал проблему для аналитиков

Тот момент, когда комментарии читал намного дольше, чем статью.

Хотелось бы больше примеров не только с Set, потому что заголовок: "Почему программистам нужно знать структуры данных и как я сэкономил компании $22 000 в год", а не "Почему программисту важно знать структуру данных Set".

И про 22к долларов не понял, откуда взялась цифра?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории