TGViewer
Никита Федькин - мысли, заметки, анонсы Никита Федькин - мысли, заметки, анонсы @nixel2007_thoughts · 2.88K subscribers
Post #278 1.9K
История одного контракта.

Поотнимаю немного хлеб у Лягуха и напишу пост про джаву.

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

В частности джава славится своими коллекциями и интерфейсами (читай контрактами).

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

С интерфейсами такая же ситуация, их ооочень много. Часть интерфейсов обрабатывается самой JVM. Например, Serializable разрешает виртуальной машине применять к классу штатный механизм бинарной сериализации. А Iterable разрешает перебирать объект в цикле for each (для каждого) - круто же! Реализовали один метод и теперь объект можно циклом обходить.

Часть интерфейсов - прикладные.
Например, задача интерфейса Comparable - дать единый метод сравнения объектов одного класса. Сказать, что этот объект "больше", "меньше" или "равен" другому объекту именно в плане порядка/сортировки. Да даже List - это тоже интерфейс. Если писать код "правильно", опираясь на интерфейсы, то реализацию конкретного листа при необходимости можно менять безболезненно.

Какая может быть необходимость?

В грядущем (и долгожданном) релизе BSL Language Server под версией 0.20.0 появится важная фича - добавленный пару релизов назад механизм Reference Index, хранящий данные о вызове всех методов в коде и помогающий делать всякие "переход к определению", "поиск мест использования" и прочие всплывающие подсказки, научился хранить ещё и данные обо всех используемых переменных - где они были объявлены/им были присвоены значения и где к этим переменным было обращение. По всей кодовой базе.

Конечно же, это довольно сильно ударило по объёму занимаемой оперативной памяти. Если в релизе 0.19 данные индекса ПО вызовам методов в УХ занимали чуть меньше 100 мегабайт оперативной памяти, то загрузка в индекс всех данных об используемых переменных резко подняла этот показатель до почти 800 (!) мегабайт. Так как вопрос производительности работы с индексом не стоял (спасибо Эдуарду за несколько подходов к оптимизации), надо было попробовать снизить затраты памяти, пускай и жертвуя толикой производительности.

В качестве основного хранилища данных ссылок в индексе использовался ConcurrentHashMap - это почти как обычный HashMap, хранящий данные в хэш-таблице на основе, собственно, хэш-кода от ключа соответствия мапы, но поддерживающий работу в многопоточной среде без ошибок или адовых ожиданий на блокировках. Покурив интернетики была найдена другая штатная реализация конкурентной мапы в виде ConcurrentSkipListMap. В ней гарантируется O log(n) на операциях поиска и вставки по ключу в отличии от вообще отсутствия каких-то гарантий по сложности в ConcurrentHashMap. Ещё и внутренняя реализация в виде индексного дерева из двунаправленных связных списков позволяла предположить, что можно сэкономить сколько-то памяти. И да, сколько-то сэкономилось - целых 200 мегабайт! От исходных 800 это целых 25%, потери же производительности были прям совсем мизерными.

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

Над реализацией метода сравнения я думал примерно ХеракХеракИГотово - если объекты равны между собой, значит они равны и по порядку. А если не равны, возьмём их хэш-код (для этого у каждого объекта в джаве есть соответствующий метод) и сравним их между собой. У кого хэш-код больше, тот и "больше" с точки зрения сортировки. А если меньше, то соответственно "меньше". Простота и красота, казалось бы... Побенчмаркали, потестили и влили.

А потом началось странное...
  • 👍 17
More from @nixel2007_thoughts
  1. Oct 15, 2026Компьютерики шутят (с)
  2. Oct 11, 2026Когда устал пилить опенсорс, подобрел и решил открыть свой магазин одежды.
  3. Sep 28, 2026Вторую картинку в посте потерял. Вот так менять/задавать пароль.
  4. Sep 28, 2026Если вы можете прочесть этот пост, то вероятно, ваш телефон находится, кхм-кхм, за границе…
  5. Sep 28, 2026video post
  6. Sep 28, 2026#анонс Полишинеля Я разрываюсь между двумя фразами на анонс, пускай будут обе: 1. Мы строи…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →