The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Отчёт о развитии FreeBSD за первый квартал 2020 года"
Отправлено Ordu, 15-Апр-20 19:39 
>>потом эту data парсишь заново
> Ну и что? Где-то будет иначе? Всё равно обходить всё заново.

Нет. json парсится в хеш-таблички, поиск в хештабличке и вставка туда элемента -- это O(log N). Если ты выполняешь это N раз, то ты получаешь O(N*log(N)), что в принципе терпимо.

>>time
> Замерять по одному вызову такое себе, надо выполнить хотя бы 10 и
> брать среднее, и то может там в фоне что-то крутится эдакое.

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

>>Что он там делает
> Емнип там интерпретатор байткода (много фишечек, да), так что не так и
> много. Весь питон со штатным json кстати столько же примерно инициализируется,
> поэтому заменять на него смысла и нет. Памяти точно в тысячи
> тысяч раз больше уйдёт, и скорее всего медленнее будет.

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

на пайтоне нет проблем написать скрипт, который будет читать строки вида ."key" += {"item":["value"]}, парсить их в три локальные переменные key, item и value, а потом делать data[key][item]=value. То есть весь код будет выглядеть так (warning: псевдокод, я не помню python'а и не знаю его API для работы с json'ом):

def read_input_line():
    // тут мы читаем входную строку, парсим её в три строки и возвращаем их

while (key, item, value) = read_input_line():
    data[key][item] = value
print(json_to_string(data))

> где-то есть более быстрый и удобный процессор жсона? Я просто
> раньше питон с этими целями использовал в скриптах, но jq более
> быстрый.

Для быстроты основной подход -- процессить не json, а структуры в памяти. В нативные для языка структуры в памяти. И после процессинга сериализовать в json. Если ты в bash напишешь скрипт, который соберёт все эти строчки в ассоциативный массив ассоциативных массивов, а потом сериализуешь эту конструкцию в json, у тебя получится быстрее чем 500 запусков jq, написанного на C. Но у bash, что-то мне подсказывает, есть проблемы с ассоциативными массивами ассоциативных массивов, потому как, видите ли, поддержка такого "ненужна", потому что всегда можно сделать что-то типа:
$data[$key@$item]=$value

Или это в awk так? Где-то такая офигительная оптимизация работы с хештабличками точно заботливо навязывалась программисту. Типа это быстрее. Я, за давностью лет, не помню где.

А насчёт удобства -- я не знаю, я с json'ом сталкиваюсь эпизодически, и поэтому не особо парюсь об удобстве, пишу на том языке, на котором столкнулся с json'ом.

Я бы, будучи на голову ушибленным rust'ом, написал бы всё на rust'е. Собственно, я и написал:

// сначала тут ~70 строк описывающих генерацию charset'а, и троек случайных строк в этом charset'е, и затем:
fn main() {
    let mut rng = rand::thread_rng();
    let charset = generate_charset("a-zA-Z0-9").expect("Invalid charset");
    let mut data: HashMap<String, HashMap<String, String>> = HashMap::new();
    for _ in 0..2000 {
        let (key, item, value) = random_addition(&mut rng, &charset);
        let entry = data.entry(key).or_insert(HashMap::new());
        entry.insert(item, value);
    }
    println!("{}", serde_json::to_string(&data).expect("Fuck up"));
}

Тут генерится 2000 троек случайных строк (key, item, value), они добавляются в хеш-табличку хеш-табличек, и потом всё это сериализуется при помощи serde_json::to_string();

$ time cargo run >/dev/null
   Compiling gen-strings v0.0.1 (/home/rgo/tmp/jq-test)
    Finished dev [unoptimized + debuginfo] target(s) in 5.14s
     Running `target/debug/gen-strings`

real    0m5,781s
user    0m1,961s
sys    0m0,412s

И это отработала версия собранная без особых оптимизаций в debug варианте. Что гораздо хуже, запущенная через cargo, который прежде чем запускать компилировал. Если эту логику написать на python, bash или чём угодно ещё, то оно будет в разы быстрее, потому что не нужна сложная компиляция.

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
  Введите код, изображенный на картинке: КОД
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру