Найти тему
47 подписчиков

Почему красивый код и оптимальный — это две разные вещи


Собственно сейчас всё ещё ковыряя графы, у меня появился пример. Вообще амбицию засунуть 150к вершин графа в WebGL я оставил. Ну точнее это реально, но с бекендом, правильным маппингом типа BSP и т.п. Так как браузер по памяти тупо не вывезет даже на уровне данных о графе с позициями вершин. Понятное дело что трансформы и прочее можно было бы вынести в пулл, но тут как я считал, что оптимальна система "мозг бек — фронт рисует". Так и собственно оказалось. Но думаю 10к запихаем)

А причём здесь оптимальный и красивый код? Ну можно посмотреть на картинку 1 и картинку 2. Я откатился к картинке 2, так как цели теперь не такие зверские и в целом можно пережить, но в чём между ними разница? Кроме компактности записи и каких-то странных буфферов? (хотя всё написано в комментах)

Так как приложение однопоточное (веб жеж) мы можем использовать хак заведя просто статические буфферы для некоторых операций (важно чтобы в начале операции буффер очищался, чтобы буфферы были стейтлесс) И тогда вот возникает какой нюанс. На 168к вершин (именно такой граф я по началу ковырял) — Linq каждый расчёт позиций граффа аллоцирует 8мб в кучу. А хак буфферы 40 байт (можно свести к нулю, но это надо избавится от хешсета, чтобы не было аллокации его итератора)

Это очень хитрый контракт, не самый лучший код, но когда мы идём к каким-то краевым задачам, то появляются такие вот вещи. Поэтому оптимальный код и красивый/удобный код — это две разные вещи :) Да, такой код очень опасен и неудобен, но при этом он работает на порядок быстрее реализации на LINQ. Можно конечно изменить модель данных, чтобы получать соседей без LINQ конструкций, но с графами есть такие нюансы, что в зависимости от используемой модели есть свои плюсы и минусы) Скажем если вершины знают своих соседей, а не это ответственность структуры графа. Но в моей задаче это не так важно. При решении конкретной задачи я бы подбирал модель данных под неё :)
1 минута