Re
Берешь рейлиб и учишь делать игры
меня всегда это поражало. так и хочется людям сразу сказать ....иди объясни нубу как сделать хеш карту на си)
Vlad
А зачем с самого нуля нубу хэш карта?
Re
Базовая структура, после двусвязных списков.
Vlad
Меня это тоже поражает, как люди думают, что раз геймдев, то сразу надо давать самый пиздец
Re
при чем тут самый? контекст идет на обучение. Базовые коллекции нужны.
Re
да даже связный список или двумерные массивы на си эта та еще попаболь
Vlad
А на луа вы сразу сделаете хэш-карту и объясните нубу, как это делается, да ещё и нахрена
Re
она есть это таблица
Vlad
Отлично. То есть обучения хэш-таблицам нет вообще (:
Re
нет, она есть. ты просто используешь и рассказываешь как и где.
Vlad
Ну новички так и Реакт изучают без жаваскрипта. Просто используют без понимания, как оно там вообще устроено.
Vlad
Ладно, мой аргумент не в том, что с нуля надо обучать Си, и вообще я отвечал исключительно на вопрос "чем человеку себя развлечь на Си?". Речи о полном нубстве не было
Re
Там был контекст.
Vlad
Да, вижу
Vlad
Anyway никто не мешает освоить сначала простейшие концепты, сделать простейшую графическую поделку на рейлибе на Си, и только потом переходить к этим вашим хэш-таблицам и прочему
Re
какой смысл? проблем то меньше не станет. интерфейсы и другие паттерны, ооп в целом. все это хочется объяснять максимально удобно и красиво. без лишнего и при этом не зацикливаясь на реализации. луашные таблицы помогают это делать и в прямом смысле это легко перенести на другой яп.
Luсky
луажит оказался примерно в 4 раза медленнее .NET 7.0 в этой задаче
Чтоб ускорить код в луажите используй ffi и указание типов переменных. И ты оху удивишься.
Luсky
Lua+FFI vs. JavaScript / Хабр https://habr.com/ru/articles/113804/
Михаил
Lua+FFI vs. JavaScript / Хабр https://habr.com/ru/articles/113804/
мммм, спасибо за подгон)) я думал, такие типы уж придется самому пилить)
Snusmumriken
мммм, спасибо за подгон)) я думал, такие типы уж придется самому пилить)
У луажыта можно спокойно объявлять кастомные типы и вешать на них метатабличку, примерно так. ffi.cdef[[ struct vec2 { float x, y; } ]] local mt = {} mt.__index = mt function mt:area() return self.x * self.y end local maker = ffi.metatype("vec2", mt) function newvec(x, y) return maker(x, y) end
Luсky
это чё, можно 3д движок на голом луажыте зделоть?
Михаил
типа [luar] struct vec2 { float x; float y; }; local mt = {} mt.__index = mt fn mt:area() return self.x * self.y local ffimeta vec2(mt); newvec = vec2;
Snusmumriken
типа [luar] struct vec2 { float x; float y; }; local mt = {} mt.__index = mt fn mt:area() return self.x * self.y local ffimeta vec2(mt); newvec = vec2;
Синтаксис питоноподобный функций всё таки довольно ужасен, по моему скромному мнению
Snusmumriken
На отступах — питоноподобный. Отсутствие границ ме.
Михаил
я просто сделал фигурные скобки опциональными
Михаил
fn mt:area() return self.x * self.y;
Михаил
так тоже можно
Михаил
но от отступов оно ни разу не зависит
Snusmumriken
А от чего зависит?
Михаил
Синтаксис питоноподобный функций всё таки довольно ужасен, по моему скромному мнению
а вообще это одна из причин по которой мы все юзаем луа, а не питон)
Михаил
А от чего зависит?
представь что кроме return ничего нет
Михаил
но есть выражения после
Михаил
return a.x * a.y print(7)
Михаил
доя луашного парсера очевидно что первое выражение заканчивается на a.y
Михаил
а за отсутствием фигурных скобок по моим правилам парсится всего одно выражение
Михаил
вот и вся магия
Михаил
UtoECat
а за отсутствием фигурных скобок по моим правилам парсится всего одно выражение
Мне кажется это может быть весьма error-prone, как на сишке порой
Михаил
Мне кажется это может быть весьма error-prone, как на сишке порой
нуу.. хз. когда знаешь где конец- почему нет
Михаил
имхо вот кто знает что он часто синтаксически ошибается и может не заметить, пусть и юзает скобочки в обязательном порядке. я даже в шарпе не юзаю часто
Михаил
и на моей памяти нет такого что такой синтаксис if (smth) dosmth(); else qwerty(); меня подводил
Михаил
но у меня уже есть лучшее решение
UtoECat
и на моей памяти нет такого что такой синтаксис if (smth) dosmth(); else qwerty(); меня подводил
Когда приходится писать будучи уставшим с подтупленным вниманием - может. Но это ладно. Я бы больше настаивал на соответствие оригинальному синтаксису, чтобы если что - переучиваться сильно не приходилось, или мешать синтаксис ванильный и вот этот. Два пропущенных символа роли не сыграют, более того - за тебя их расставит ide.
UtoECat
но у меня уже есть лучшее решение
Ждём тогда новостей на этот счёт 😁
Михаил
Ждём тогда новостей на этот счёт 😁
эти три функции будут эквивалентными [luar] local foo = fn(x) x * x; local bar = fn(x) { return x * x; } [lua] local baz = function(x) return x * x end;
Михаил
[luar] local fn multiple(x, y) x + y, x * y, x % y local a, b, c = multiple(12, 8)
Михаил
это весьма просто сделать
Михаил
вот я изо всей силы обмазался FFI, но перф получился в 2 раза ниже
Михаил
Михаил
UtoECat
вот я изо всей силы обмазался FFI, но перф получился в 2 раза ниже
А ты преран сделал чтобы jit компилятор скомпилил трейсы? Сто раз позапускай без замера, и потом 1 раз с замером. Разумеется в одном стейте, не тупо файл запустить сто раз заново.
Snusmumriken
Луажыт любит прямой код, минимум ветвлений, и от 500к прогонов.
Михаил
в байткоде CDEF содержится прямым текстом, и это настораживает
UtoECat
Михаил
Ну так байткод != скомпилированный трейс
я понял, но я раньше хотел это вставить. не ответ на то сообщение
Михаил
кто может знает функцию, которая на все ненулевые значения аргумента будет выдавать 0, а иначе 1? только без ветвлений
Михаил
оо, целые типы FFI принимают булевые значения, кайф)
Михаил
Луажыт любит прямой код, минимум ветвлений, и от 500к прогонов.
ОК. Ветвления удалены local function main(num) local c = newvec5(0, 0, 0, 0); while (c.w < num) do local d3, d5, d7 = c:d3(), c:d5(), c:d7(); c.t = d3; c.x = c.x + c.t; c.t = ((not d3) and d5); c.y = c.y + c.t; c.t = ((not d3) and (not d5) and d7); c.z = c.z + c.t; c:incw(); end return tonumber(c.z), tonumber(c.x), tonumber(c.y); end результат: 8.5 сек вместо прежних 6 сек
Михаил
UtoECat
Ну так ты не добавил стадию подготовки, чтобы компилятор скомпилил функцию main...
Михаил
вот убрал луашные операторы and not и заменил умножением, результат 11 сек
Михаил
лан щас сделаю
Михаил
Михаил
Ну так ты не добавил стадию подготовки, чтобы компилятор скомпилил функцию main...
стадия подготовки - скомпилировать в байткод? с байткодом перф примерно такой же
UtoECat
стадия подготовки - скомпилировать в байткод? с байткодом перф примерно такой же
убрал метаметоды - стало 4 секунды время выполнения function main(num) local c = newvec5(0, 0, 0, 0); while (c.w < num) do local d3, d5, d7 = c.w % 3 == 0, c.w % 5 == 0, c.w % 7 == 0; c.t = d3; c.x = c.x + c.t; c.t = ((not d3) and d5); c.y = c.y + c.t; c.t = ((not d3) and (not d5) and d7); c.z = c.z + c.t; c.w = c.w + 1; end return tonumber(c.z), tonumber(c.x), tonumber(c.y); end
UtoECat
а у меня там 6 сек
а c# сколько занимает? на твоей машине?
Михаил
дотнет 7.0
Михаил
пока что лучше всего себя ведет этот код local function main(num) local c5 = 0; local c3 = 0; local c7 = 0; local i = 0; while i < num do if (i % 3 == 0) then c3 = c3 + 1; elseif (i % 5 == 0) then c5 = c5 + 1; elseif (i % 7 == 0) then c7 = c7 + 1; end i = i + 1 end return c7, c3, c5; end local n = tonumber(...); local c7, c3, c5 = main(n); print("c7: "..c7.." c3: "..c3.." c5: "..c5); 3.4 сек