172 похожих чатов

Я не знаю, насколько моя идея фантастическая, но всё же

спрошу.
Задача: есть данные (структура такая же как и в БД: несколько столбцов и много строчек), они хранятся в файле, у которого свой формат, надо их обработать.
Формат файла такой: сначала идёт схема/описание "столбцов" (тип данных, количество байт, которое нужно на хранение, название "столбца"), а далее идут непосредственно данные, которые надо парсить исходя из описания (схемы). И написать парсер было легко (пришлось, конечно, дублировать тип данных и сами данные).
enum T {
Int32(i32),
Float(f32),
Double(f64),
...
}

enum TType {
Int32,
Float,
Double,
...
}
Однако в парсере при каждом считывании ячейки нужно знать тип (берётся из схемы) и по нему определять, сколько байт надо считать и каким образом превращать байтики (например, для Int32 это будет i32::from_le_bytes, для Float это будет f32::from_le_bytes). И из-за этого приходится делать что-то такое:
match ttype {
TType::Int32 => ...,
TType::Float => ...,
TType::Double => ...,
...
}
И это создаёт слишком много branch instructions (надеюсь, я правильно использую термин). Можно ли от них избавиться?

Вообще исходная идея была такова: каким-то чудом парсить данные (после того как мы знаем схему), не делая pattern matching (в общем, избавиться от branch instructions). Это вообще можно реализовать?

Пока я писал этот текст, я понял, что можно было бы использовать HashMap (по типу сразу достать функцию, которую потом вызвать)

15 ответов

19 просмотров

матч и так может скомпилится в хэшфуннкцию или дерево, как оптимизация

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

ㅤ-Атеист Автор вопроса
Dmitry Rodionov
Если тебе такое подойдёт можешь посмотреть на поко...

Конечно, я не смогу изменить формат данных, но читать по колонкам данные я смогу

ㅤ Атеист
Конечно, я не смогу изменить формат данных, но чит...

Надо смотреть, если файл большой то может так получиться что ты его несколько раз читаешь, и если он в page cache операционки не поместится то ещё и прям с диска будет несколько раз данные запрашивать, и это будет сильно дольше чем ещё один if

ㅤ Атеист
Конечно, я не смогу изменить формат данных, но чит...

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

ㅤ-Атеист Автор вопроса
Dmitry Rodionov
Ещё одна мысль, у тебя же схема на протяжении файл...

Да, схема одна и та же. А сопоставить можно с помощью того же HashMap?

ㅤ Атеист
Да, схема одна и та же. А сопоставить можно с помо...

Должно и вектора хватить, номер поля в схеме -> индекс в векторе

ㅤ Атеист
Да, схема одна и та же. А сопоставить можно с помо...

можно даже при парсинге прям по этому вектору итерироваться

А потом лукапаться по хешмапе дороже будет)

Нафига и зачем хэшмапа, если матч сделан практически в стиле switch-case, где у него и так будет наиболее оптимальная табличка? Без всякого хэширования, лазания в кучу и проверок наличия индекса с двойными лукапами.

Пух
А потом лукапаться по хешмапе дороже будет)

и это тоже да, хешировать инты по идее должно быть дешево, но все равно дороже чем просто индекс

ㅤ-Атеист Автор вопроса
Traveller Kolsky
Нафига и зачем хэшмапа, если матч сделан практичес...

Может, я что-то не так делаю или не понимаю, но тут есть переходы: https://godbolt.org/z/hE3xzo3Md (14 строчка)

ㅤ-Атеист Автор вопроса
ㅤ Атеист
Может, я что-то не так делаю или не понимаю, но ту...

Наверное, можно было бы сделать как-то так: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ee3a429ec2cb50764eae681f998c771c

Использовали бы wrapping_mul, если полагаетесь на него

ㅤ-Атеист Автор вопроса
вафля'
screenshot Использовали бы wrapping_mul, если полагаетесь на ...

Да, действительно... Это всё из-за переполнений (упростил функции, чтобы точно не было переполнений и всё ок. Паттерн матчинг быстрый стал)

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
Ребят в СИ можно реализовать ООП?
Николай
33
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
2
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Карта сайта