Snusmumriken
Так а мы же от конкатенации уходим,а тут она, родимая...
Смотри на количество элементов. До условных 10 небольших элементов, эвристически конкатенировать быстрее чем мутить таблички.
mva
Так а мы же от конкатенации уходим,а тут она, родимая...
конкатенация строки в цикле, НЯП, дороже наполнения таблицы в цикле и последующей конкатенации таблицы
Snusmumriken
мелочёвку норм конкатить
Денис
Да ну нафиг читать всякое! Я лучше у вас спрошу! 😀
Денис
Вон, тут попросили ООП намутить. Намутил. Надо будет вам на растерзание сбросить, чтобы понять чего там не так.
Snusmumriken
Чем вот так будет плохо? function string.joinsep(orig, sep, ...) return table.concat({orig, ...},sep) end
Хорошо при джойне огромных строк, хреновато при джойне крошечных, особенно если промежуточные результаты их объединений уже есть в стрингбуфере.
Snusmumriken
И оно будет неправильно работать при nil'ах в orig или "...", вот эта штука правильно вернёт правильные ошибки. table.concat((table.pack or pack)(orig, ...), sep)
Vyacheslav
И оно будет неправильно работать при nil'ах в orig или "...", вот эта штука правильно вернёт правильные ошибки. table.concat((table.pack or pack)(orig, ...), sep)
Ну это вы уже закладываете дополнительные условия. Неочевидности с nil вообще не понятны. Concat будет работать быстро, т.к. он на Си с предподсчетом всех длин строк из таблицы и одним выделением памяти.
Vyacheslav
Из минусов - одна аллокация таблицы, но с этим можно жить, имхо.
Vyacheslav
Логичнее с моей точки зрения было бы добавить что-то вроде function string.join(sep, ...) return table.concat({...}, sep) end Использование: (","):join("a","b","c")
Snusmumriken
Из минусов - одна аллокация таблицы, но с этим можно жить, имхо.
Просто замерь разницу с разметкой таблицы или конкатом строк в разных случаях, и выбери предпочтительный. У меня есть опытная эвристика.
Vyacheslav
Скорость работы при использовании конкатенации будет уже зависеть от размера строк. Случай использования таблицы не самый быстрый, но без таких "подводных камней"
Snusmumriken
Разумеется.
Snusmumriken
Но эвристика показывает что joinsep'ом куда чаще будут объединять маленькие строчки. Они даже не в таблице, чел.
Snusmumriken
Если хочешь расширить, посчитай сумму байтиков в склеиваемых строчках, можешь заточиться под это, и если конечный объём меньше килобайта а количество элементов меньше десятка — использовать склейку, а если больше — тейбл.конкат. Всё в твоих руках.
Vyacheslav
Но эвристика показывает что joinsep'ом куда чаще будут объединять маленькие строчки. Они даже не в таблице, чел.
Интересно было бы послушать, как вы применяли эвристику и методологию замеров скорости. Спрашиваю оттого, что любая строка, созданная в Lua попадает в weak reference внутренний словарь строк, откуда потом будет вычищаться сборщиком мусора. table.concat продуцирует ровно одну строку. Оператор .. также продуцирует одну строку. table.concat в зависимости от параметров сборки Lua может брать блокировку на стейт машину Lua. .. так не делает. Не в этом ли может быть ускорение? (Что не учитывается сбор мусора и использование сборки с блокировкой)
Snusmumriken
Создание таблички неизвестного размера и её переразметка делает примерно то же самое.
Vyacheslav
Так в случае {...} размер известен
Snusmumriken
Если добавить функционал table.new(select("#", ...), 0), то было бы проще, табличка с однократной разметкой.
Snusmumriken
Так в случае {...} размер известен
Надо будет чекнуть байткод.
Snusmumriken
Байзевей никогда не пакуй туплы в {...} напрямую, только через table.pack который нормально переносит все значения и добавляет ключ n, а table.unpack вполне себе использует этот ключ и возвращает ровно тот тупл который был запакован.
Vyacheslav
Байзевей никогда не пакуй туплы в {...} напрямую, только через table.pack который нормально переносит все значения и добавляет ключ n, а table.unpack вполне себе использует этот ключ и возвращает ровно тот тупл который был запакован.
В 5.2 была локальная переменная arg. Не знаю, осталась ли сейчас. В ней как раз {...} Поэтому рекомендация не понятна. Да, я знаю, чем отличается pack, но считаю это преждевременной оптимизацей
Snusmumriken
В ней должна быть не {...} а table.pack(...). Проверь наличие ключа arg.n.
Vyacheslav
Ну ссылку на документацию по Lua-то можно?
Snusmumriken
Не а, ты новичок
Snusmumriken
После суток можно будет
Vyacheslav
Из консоли Termux arg сейчас не даёт использовать. Не у компьютера, чтобы проверить
Vyacheslav
Тут как раз по делу lua.org/pil/5.2.html
Vyacheslav
Как было в 5.2
Lucky
Ну ссылку на документацию по Lua-то можно?
А смысл? Её сотни в файлах чятика.
Snusmumriken
Этот arg — это аргументы командной строки при запуске приложения, это не локальные аргументы функции.
Vyacheslav
Этот arg — это аргументы командной строки при запуске приложения, это не локальные аргументы функции.
По ссылке выше When this function is called, all its arguments are collected in a single table, which the function accesses as a hidden parameter named arg.
Igor
Надо будет чекнуть байткод.
очень вряд ли при создании таблицы из вариативки берётся размер самого варарга, процентов на 90 уверен, что там реаллокация
Snusmumriken
Качаю блин 5.2
Vyacheslav
В глобальном неймспейсе - да, в вариадик - нет
Snusmumriken
В 5.3, время качать 5.2
Vyacheslav
Качаю блин 5.2
Только в неинтерактивном режиме надо проверять. В терминале не работает
Snusmumriken
Омг
Vyacheslav
В 5.3, время качать 5.2
Не из консоли, а с файла только
Vyacheslav
Консоль так не работает от чего-то. Консоль цепляет глобал как раз
Snusmumriken
Хммм
Vyacheslav
Хммм
print(_VERSION) ?
Snusmumriken
print(_VERSION) ?
У тебя блин скриншот, или ты думаешь я обманываю? ) _VERSION тоже можно переписать кста. Но я только что скачал бинарь для 5.2.4, можешь сделать то же самое.
Snusmumriken
Тут как раз по делу lua.org/pil/5.2.html
И если посмотреть на доку, можно посмотреть что там есть ключ n=0 или n=2, что ясно указывает на результат table.pack.
Vyacheslav
Snusmumriken
Вот это очень странно, потому что в 52.exe никак не может подгружать 53.dll если в нём самом не прописаны фолбеки. Имя шаред либы должно быть совершенно конкретное, иначе бы все либы а ля openal32 и openal64 пытались бы подгружать друг друга с закономерным результатом.
Vyacheslav
Вот это очень странно, потому что в 52.exe никак не может подгружать 53.dll если в нём самом не прописаны фолбеки. Имя шаред либы должно быть совершенно конкретное, иначе бы все либы а ля openal32 и openal64 пытались бы подгружать друг друга с закономерным результатом.
Зависит от того, как выполнен отладчик. Отладчик Lua может быть привязан к конкретной версии. Если нет отладчика в запуске, то у меня только вопрос про конкретный релиз 5.2. Может, Роберт удалил этот arg при обновлении. И я не хотел бы спорить насчёт {...} vs pack. У каждого свои предпочтения. Насчёт скорости, соглашусь, что нужно замерять.
Vyacheslav
Люди вот такое вытворяют, поэтому я не удивляюсь, а лишь проверяю stackoverflow.com/q/40547638/1836540
Snusmumriken
Зависит от того, как выполнен отладчик. Отладчик Lua может быть привязан к конкретной версии. Если нет отладчика в запуске, то у меня только вопрос про конкретный релиз 5.2. Может, Роберт удалил этот arg при обновлении. И я не хотел бы спорить насчёт {...} vs pack. У каждого свои предпочтения. Насчёт скорости, соглашусь, что нужно замерять.
И я не хотел бы спорить насчёт {...} vs pack. У каждого свои предпочтения. Тут нет предпочтений. {...} не позволяет точно распаковать наборы значений вроде {1, 2, nil, 5, nil, nil}. # не сможет определить длину, споткнувшись о случайный nil, потому что использует бинарный поиск. ipairs споткнётся об первый же nil. pairs/next определит только граничные не-nil-значения, он не в курсе что там есть хвост из nil'ов. Поэтому есть только два способа упаковывать варарги в таблицу — pack или — вручную перебирать через select, плюс указать точное значение элементов, то есть вручную сделать то же что делает pack. ВСЕ другие способы приводят к потерям данных. Точка.
Vyacheslav
И я не хотел бы спорить насчёт {...} vs pack. У каждого свои предпочтения. Тут нет предпочтений. {...} не позволяет точно распаковать наборы значений вроде {1, 2, nil, 5, nil, nil}. # не сможет определить длину, споткнувшись о случайный nil, потому что использует бинарный поиск. ipairs споткнётся об первый же nil. pairs/next определит только граничные не-nil-значения, он не в курсе что там есть хвост из nil'ов. Поэтому есть только два способа упаковывать варарги в таблицу — pack или — вручную перебирать через select, плюс указать точное значение элементов, то есть вручную сделать то же что делает pack. ВСЕ другие способы приводят к потерям данных. Точка.
t={...}; return #t вернёт длину без хвостовых nil. Это единственное, что может потеряться при сравнении с pack. В языке, где лишние параметры функций просто отбрасываются, считаю это разумным компромиссом. function g(v) end g(1,2,3) Кроме этого, в случае pack в дополнение к выделению памяти под индексную часть будет выделение памяти под key-value хранилище (хэш) ключей в таблице — под ключ "n". В случае {...} выделяется только память под индексную часть. Оттого эта {...} конструкция и существует, логично вписываясь в сделанные компромиссы при реализации интерпретатора и концепцию языка.
Vyacheslav
Вводить ли в code style какой-то конкретной компании или проекта требование использовать pack вместо {...}, по моему мнению, — дело авторов проекта или технического менеджмента компании. Я уважаю ваш выбор, если вы предпочитаете pack, и даже если будете рекомендовать его новичкам. Я лишь против навязывания вида "Тут нет предпочтений." Я понял, что у вас их нет, но они могут быть у других разработчиков.
Vyacheslav
потоковое чтение для json не сделать, т.к. только дойдя до конца можно понять, что коллекция/массив в json валидная. Но есть jsonl, который можно по-строчно парсить, именно что в поточном режиме
В общем общем случае можно, в виде автомата состояний, но на выходе будет поток вызовов beginobject, endobject, beginarray, endarray, newkey, newtoken etc. И в процессе их "проигрывания" не будет известно, валидный ли JSON пришёл на вход. Это знание появится на последнем вызове endobject, если он произойдёт.
Денис
А если джойнить через string.format? Составить шаблон через string.rep и ухнуть в нее инфинити? Насколько это будет быстро по наблюдению?
Денис
Хотя, чему там тормозить. . . Сишное все. Памяти потратится только на шаблон, чанки в параметрах и результирующую строку.
Денис
А и вообще, стоит ли на это задрачивать?.. пишу не для маленьких железок, расчет на бытовые компы. . . Когда буду писать под что-то маломощное, тогда и буду оптимизировать все, что движется. . .
Snusmumriken
t={...}; return #t вернёт длину без хвостовых nil. Это единственное, что может потеряться при сравнении с pack. В языке, где лишние параметры функций просто отбрасываются, считаю это разумным компромиссом. function g(v) end g(1,2,3) Кроме этого, в случае pack в дополнение к выделению памяти под индексную часть будет выделение памяти под key-value хранилище (хэш) ключей в таблице — под ключ "n". В случае {...} выделяется только память под индексную часть. Оттого эта {...} конструкция и существует, логично вписываясь в сделанные компромиссы при реализации интерпретатора и концепцию языка.
Чел.. Ты слышал что-то про бинарный поиск? Пора привыкнуть, что если я что-то говорю, под это существуют совершенно конкретные объективные причины, и если я ДЕСЯТЬ раз повторяю одно и то же — значит это проверено многократно и я тут в своё время успел обосраться раза три. table.len использует тот же самый тот же бинарный тот же поиск, поэтому смухлевать не получится. На тему хвостовых nil — от них может зависеть логика, например в местах где отправка nil'ов чаще приводит к ошибкам, и надо ругнуться "чел ты мне nil послал последним аргументом, почему всё таки послал а не опустил этот аргумент?".
Vyacheslav
На тему хвостовых nil/ не-nil, я привёл аргумент, что так же невозможно в вызываемой Lua-функции с фиксированным числом параметров проверить, что передано больше параметров, чем нужно.
Snusmumriken
И есть только один варик для этого — pack. Если ты вдруг не знаешь, люди обычно стараются не избегать UB любой ценой.
Денис
Будет выполняться код разбора шаблона, что, очевидно, небыстро.
Та чему там быть медленным? Функция string.format по сути выполняется на нативной стороне, это же не логика скрипта. Ну а функции такого рода в сях будут всяко быстрее, чем интерпретируемый код.
UtoECat
Если вы хотите опровергнуть мои утверждения про {...}, то используйте {...}, пожалуйста, а не оператор инициации таблицы.
Зачем вообще пытаться nilы пихать в таблицу? 😐 Если подобное и нужно, то лучше заменить nilы на false и не мучаться.
Snusmumriken
Зачем вообще пытаться nilы пихать в таблицу? 😐 Если подобное и нужно, то лучше заменить nilы на false и не мучаться.
... — это варарги. Ты вызываешь функцию: foo(10, 20, 30, _, _, 40) Если хочется запихнуть аргументы этой функции в табличку, то придётся учитывать nil'ы.
Snusmumriken
Например, возьмём ловку. Конструкция вида love.graphics.draw(img, x, y, _, _, _, 32, 32) встречается регулярно, потому что впадлу заполнять аргументы по дефолту. И кстати, там luajit (5.1). Что было бы если ловка паковала это как варарги в табличку и итерировала бы по ним? Она бы обосралась в 5.1 без pack'а.
Alxius
сделал я наконец чтобы выстрел кислоты влиял слабо очень на дроида и слабее на танка. при этом не поломав эффект коррозия. . так что игра Colony станет значительно легче. https://dj-alex.itch.io/colony В иобщем геймплей теперь будет менее хардкорным в ней. Билд 273 выбирать
Alxius
ранее я убавлял убавлял урон врагам. а он не убавлялся, потому что убивал не урон а навешанные дебаффы (яд) просто постоянно -1 отнимал.
Snusmumriken
Яды это вообще бич кучи старых игр
Snusmumriken
Ну там, где-то в далёком 98 году приравняли скорость тиков ядов к фреймрейту. На старом компудахтере игра работает в 20 fps, и там тики нормальные. На современном 600 fps и яды шотают, стоит мизинчиком наступить в лужицу. Или нечто аналогичное.
UtoECat
Например, возьмём ловку. Конструкция вида love.graphics.draw(img, x, y, _, _, _, 32, 32) встречается регулярно, потому что впадлу заполнять аргументы по дефолту. И кстати, там luajit (5.1). Что было бы если ловка паковала это как варарги в табличку и итерировала бы по ним? Она бы обосралась в 5.1 без pack'а.
Хмм... Не думал, что это так может работать 😐. Обычно я все дефолтные аргументы прописываю полностью... Оно и читается потом легче, не надо додумывать что там должно быть... Но всё равно интересно.
Snusmumriken
Я просто даю пример где бы был обсёр. Понятное дело что сама ловка не использует варарги в таких местах.
Snusmumriken
Но она использует варарги в функциях вроде полигона, и вот там, если вдруг встретился nil — это явная ошибка, которая может быть пропущена в случае использования чего-то {...}-подобного, и хрен отладишь и хрен поймёшь почему это у тебя рисуется только кусок полигона вместо целого.
UtoECat
Я просто даю пример где бы был обсёр. Понятное дело что сама ловка не использует варарги в таких местах.
Я вообще стараюсь не паковать варарг в табличку - лишний объект только создавать 😁
Alxius
Но возможно реально надо фпс и скорость игры учитывать