Anonymous
Из-за этого без сишной либы вывод на текстовый lcd экран дико ториозит.
Snusmumriken
Косяк с таймаутами.
Anonymous
А что за таймауты?
Snusmumriken
Ну, когда ты считаешь с ноги строку - нужно некоторое время подождать, пока строке не придет полностью, если она длинная.
Alexander
какая строка, одно считывание гпио ж один бит
Anonymous
Да я просто пин читаю, без символов и всего этого.
Alexander
да и чтение из символьного буфера обычно тоже быстренькое. как в уартах
Snusmumriken
Не исключено что где-то сэкономили при разработке прошивки, потому что вызов сишной функции у луа не имеет практически никакого оверхеда.
Snusmumriken
Сэкономили в плане объема кода.
Anonymous
Да куда там ещё экономить, по идее там функции тривиальны. Разве что надо преобразовать условный номер пина в его фактическое расположение.
Anonymous
А работа с таблицами не может тормозить?
Snusmumriken
Можешь попробовать обновить прошивку, авось пофиксили.
Snusmumriken
Может, но слабо, и совсем не на 100мс.
Snusmumriken
Скинь код на pastebin
Anonymous
http://pastebin.com/1EP5fixy
Anonymous
Тайминги замерял снаружи лог.анализатором
Tverd
Попробуй заменить до цикла self.pins['E'] переменной
Anonymous
Ага, надо будет попробовать.
Anonymous
Но один фиг, не хардкодить же номера пинов в либе
Tverd
ну это понятно, но хотя бы будет более понятно, что затык не в этом
Snusmumriken
dev.test = function(self) local write, high, low = gpio.write, gpio.HIGH, gpio.LOW write(self.pins['E'], HIGH) Чуть-чуть ускорит за счёт кеширования, и писать короче.
Tverd
@Snusmumriken обнаружил ошибку в твоей гномьей сортировке.
Snusmumriken
Именно в сортировке? Чегось там?
Tverd
вместо local i, j = 2, 3 while i < #t do надо local i, j = 2, 3 while i <= #t do
Tverd
<= #t
Snusmumriken
Понял, понял. Хм. Сейчас думаю на что это влияет. Последний элемент не сортируется?
Tverd
Я тут небольшой тест написал. сортировка у меня убывающая. Добавляю в конец большой элемент, который должен уйти в начало. А он остается в конце списка
Tverd
да
Snusmumriken
А, да, тогда ты прав = )
Tverd
Так было задумано? )))
Snusmumriken
Конечно :3 Кому нужны скучные, правильные алгоритмы, которые делают всё как надо.
Tverd
ну блин ) В общем поправляй где-там надо
Snusmumriken
Уже, спасибо за фидбек
void *
дебаг для слабаков, надо сразу писать правильный код
Tverd
👍🏻
Snusmumriken
Люди делают ошибки, и это делает их людьми. Перечитал ницше, и теперь грызу ногти от ужаса, что я не сверхчеловек. Хе-хе-хе
Snusmumriken
Snusmumriken
Во, теперь правильно.
Alejandro Jeditobe
Alejandro: Бакалавры и Магистры! Кто хочет в Google Summer of Code 2017 попасть? Пишите в личку.
Tverd
2007? Кто-то изобрел уже машину времени??? ))))))))))))
Tverd
Ну думаю надо узнать, у организаторов, по поводу лета кода. Хотя вроде как это для студентов
Anonymous
Потестил всякие оптимизации на NodeMCU, результат следующий: Если в строке gpio.write(self.pins['E'], gpio.HIGH) заменить self.pins['E'] на переменную, то скорость остаётся той же. Если в строке gpio.write(pin, gpio.HIGH) заменить gpio.HIGH на переменную, то скорость возрастает в 2 раза Если потом заменить ещё и gpio.write на переменную, то получается прирост в 18(!) раз.
Anonymous
Если после всего этого обратно вернуть self.pins['E'], то получаем замедление в 1.2 раза. Видимо, на большой скорости обращение к этой таблице становится уже заметно.
Snusmumriken
Кешируем и пляшем. Карочи, объясняю для тех кто плохо помнит, как происходит поиск переменных. Простой пример: t = {key = 'yo'} -- 0 function foo(x, y, z) -- 1 for i = x, y do -- 2 z = z + 1 print(t.key) end end Цифрами обозначены области видимости. Каждый раз когда мы ищем t.key, мы сначала проверям на наличие таблички t область видимости 2 (содержимое цикла), ничего там не находим, ищем в области видимости 1 (функция), не находим, спускаемся в табличку _G, и внезапно находим там t. Прогоняем в ней ключ key в хеш-функции, и внезапно снова находим значение 'yo'. В результате, n = (y - x) раз, мы раз за разом проверяем эти области видимости, чтобы каждый раз найти эту самую табличку t с ключом key. То же самое с функцией print. Это не шибко круто, поэтому добавив ссылку на табличку перед циклом (а лучше - сразу дублировать ключ, если он не изменяется в процессе цикла), мы сокращаем время поиска раза в два (поиск в цикле - неудачный, поиск в функции - удачный), такие дела. Да, чем "глубже" находится объект поиска, тем медленнее поиск, думаю это очевидно. Со ссылками на (функции/таблицы) в таблицах, мы получаем ещё больше плюх, ибо они передаются как ссылки (не тратится время и оперативка на дублирование значения), и отсутствует даже поиск внутри таблички-батьки, поэтому замена gpio.write на local write = gpio.write даёт больше преимуществ, хоть и незначительно грузит сборку мусора: советую не плодить много переменных/таблиц в длинных циклах: инициализировал всё что нужно перед циклом, и обрабатывай на здоровье. Аналогично с gpio._LOW / gpio._HIGH: залокалили и нет поиска. А вот с тестами - молодец, старайся как бенчмаркать даже казалось бы обычные вещи. P. S. Прирост в 18 раз - не предел. Можно больше. С luajit ты бы получил прирост производительности в 150-400 раз, если бы загнал функцию в цикл, но увы, из-за объёма оперативки (jit имеет оверхед на разогрев трасс и их компиляции), его скорее всего не будет в nodemcu. И ты можешь сказать спасибо что это не жаваскрипт/питон, потому что чтобы оптимизировать подобное там - нужно знать гораздо больше, ибо под капотом происходит реально много неочевидных и костыльных вещей. По просьбам трудящихся, добавляю теги #lua #fyi #namelookup
Snusmumriken
Всё, спать. Приятных тем, кого я разбудил уведомлялкой.
Anonymous
Спасибо за объяснение. Правда, всё равно не понял, почему при замене gpio.write прирост в 18 раз, а при замене gpio.HIGH - только в 2. Сейчас глянул, на ноде gpio представляет собой romtable с вот таким содержимым: > for k,v in pairs(gpio) do print(k.." => "..tostring(v)) end mode => lightfunction: 40253a54 read => lightfunction: 40253a08 write => lightfunction: 402539b0 serout => lightfunction: 40253b28 trig => lightfunction: 402538cc INT => 2 OUTPUT => 1 OPENDRAIN => 3 INPUT => 0 HIGH => 1 LOW => 0 FLOAT => 0 PULLUP => 1 По идее, если там идёт линейный поиск, то функцию write найти проще, чем константу HIGH.
Snusmumriken
Хз ))) Надо отдельно смотреть или влезть в сурцы gpio. P.S. Функцию write найти так же затратно, как константу HIGH. Только запоминается ссылка на неё (типа указатель), а не значение.
Anonymous
Я так понимаю, запомнить ссылку должно быть дешевле, чем значение?
Anonymous
А не, это я туплю. Доступ к gpio.HIGH тоже в 18 раз дороже его отсутствия, просто в совокупности с доступом к gpio.read профит получался всего в два раза.
Snusmumriken
Ну, в общем на выходе довольно неплохо. Кеширование = хорошо, ты понял.
🦥Alex Fails
Кешируем и пляшем. Карочи, объясняю для тех кто плохо помнит, как происходит поиск переменных. Простой пример: t = {key = 'yo'} -- 0 function foo(x, y, z) -- 1 for i = x, y do -- 2 z = z + 1 print(t.key) end end Цифрами обозначены области видимости. Каждый раз когда мы ищем t.key, мы сначала проверям на наличие таблички t область видимости 2 (содержимое цикла), ничего там не находим, ищем в области видимости 1 (функция), не находим, спускаемся в табличку _G, и внезапно находим там t. Прогоняем в ней ключ key в хеш-функции, и внезапно снова находим значение 'yo'. В результате, n = (y - x) раз, мы раз за разом проверяем эти области видимости, чтобы каждый раз найти эту самую табличку t с ключом key. То же самое с функцией print. Это не шибко круто, поэтому добавив ссылку на табличку перед циклом (а лучше - сразу дублировать ключ, если он не изменяется в процессе цикла), мы сокращаем время поиска раза в два (поиск в цикле - неудачный, поиск в функции - удачный), такие дела. Да, чем "глубже" находится объект поиска, тем медленнее поиск, думаю это очевидно. Со ссылками на (функции/таблицы) в таблицах, мы получаем ещё больше плюх, ибо они передаются как ссылки (не тратится время и оперативка на дублирование значения), и отсутствует даже поиск внутри таблички-батьки, поэтому замена gpio.write на local write = gpio.write даёт больше преимуществ, хоть и незначительно грузит сборку мусора: советую не плодить много переменных/таблиц в длинных циклах: инициализировал всё что нужно перед циклом, и обрабатывай на здоровье. Аналогично с gpio._LOW / gpio._HIGH: залокалили и нет поиска. А вот с тестами - молодец, старайся как бенчмаркать даже казалось бы обычные вещи. P. S. Прирост в 18 раз - не предел. Можно больше. С luajit ты бы получил прирост производительности в 150-400 раз, если бы загнал функцию в цикл, но увы, из-за объёма оперативки (jit имеет оверхед на разогрев трасс и их компиляции), его скорее всего не будет в nodemcu. И ты можешь сказать спасибо что это не жаваскрипт/питон, потому что чтобы оптимизировать подобное там - нужно знать гораздо больше, ибо под капотом происходит реально много неочевидных и костыльных вещей. По просьбам трудящихся, добавляю теги #lua #fyi #namelookup
#lua #fyi #namelookup
Anonymous
Ага.
B
помощ помощ понемногу пытаюсь переехать на Atom щас поставил git-plus что б напрямую работать с гитом из атома но там как то все тяжко идет со скрипом есть у кого внятные мануалы для курения по этому поводу до этого пользовал гит десктоп понимаю что консоль мощнее но просто лень
Tverd
Насчет Атома не в курсе, но по гиту полно манов на хабре. например: https://habrahabr.ru/post/313890/
Tverd
https://habrahabr.ru/post/174467/
Tverd
Пользовал sourcetree. Это конечно если я правильно понял вопрос ) Или как работать с гитом в Атоме?
А что в git-plus со скрипом?
Есть ещё плагин, называется, ЕМНИП, git-control. Там графический интерфейс открывается во вкладке Атома.
Tverd
Тут я не знаю, этих инструментов не использовал. Ждем других )
Sergey
Source tree и github предпочитаю тоже. Не люблю коммитить из редактора.
void *
атом оч.хорошо кастомизируется ну и проприетарщина не нужна
🦥Alex Fails
Коллеги, для холиваров есть отдельный чат😊
void *
Коллеги, для холиваров есть отдельный чат😊
так это для холиваров про C++ же
🦥Alex Fails
Да там можно и про иде
В Атом тоже можно такую фичу встроить, от этого он не станет проприетарным. Это про другое совсем.
Тоже можно сделать окошко "купи лицензию".
К тому, что проприетарность и периодическое нажатие Escape друг с другом не связаны.
Она у тебя не привязана ко времени?
Как только посчитал, хочешь сразу рисовать? (Не умелец, просто интересуюсь.)
Почему не сделать вне рисования рендер в текстуру, а потом эту текстуру отрисовывать?
Что-то вроде этого.
Нет.
В одном вызове love.update будет одна твоя итерация.
Попробуй, запусти.
Идея была в том, чтобы вынести каждую отдельную итерацию цикла работы твоего генератора в вызов love.update. Каждый апдейт — 1 итерация.
Эту итерацию.
Snusmumriken
Ты не в том чате :3
Snusmumriken
@love2d_ru
@love2d_ru
О, благодарю.