eu_tomat
Модераторы-
Публикации
2 666 -
Зарегистрирован
-
Посещение
-
Победитель дней
331
Тип публикации
Блоги
Профили
Форум
Багтрекер
Магазин
Все публикации пользователя eu_tomat
-
Я нашёл чуть более производительный вариант схемы реактора: Алгоритм поиска оптимальной схемы я описал ранее: это заполнение плоскости "крестиком", перебор возможных вариантов сдвига и отбрасывание симметричных вариантов. Затем во всех вариантах я заполнял оставшиеся свободными слоты какими-то полезными компонентами и выбирал наиболее производительный вариант. В итоге я получил схему с производительностью 4280 eu/t. @whiskas поступил чуть умнее. Взяв за основу симметричный моему сдвиг сетки, он немного сместил некоторые компоненты в уже занятых слотах, благодаря чему улучшил производительность реакторной схемы до 4340 eu/t. В очередной раз погрузившись в тему реакторов, я повторил поиск лучшего варианта сдвига сетки, но теперь не просто заполняя свободные слоты, как делал это в первый раз, а более тщательно, пробуя немного сдвигать компоненты. В результате я смог немного увеличить производительность: до 4360 eu/t на уране и до 21798 eu/t на MOX-топливе. Дополнительным бонусом схемы стало отсутствие в ней отражателей, теперь используются лишь два типа компонентов. А перфекционистов может порадовать центральная симметрия схемы.
-
Если механика именно такова, а полёт автоматический, то можно сначала опускать свинью в воду, а уже оттуда поднимать на целевую площадку. А, можно, наверное, вообще спрыгивать из седла с небольшой высоты. А свинья пусть себе летит на парковку с водяным полом.
- 15 ответов
-
- 1
-
-
Конечно, не просто так. Вероятность вылета повышается пропорционально нагрузке, создаваемой скриптом. А так как нагрузка ненулевая, то и вероятность вылета тоже всегда больше нуля. Но нагрузка играет значительную роль. В этом звёзды сходятся довольно часто. Если на лагающем сервере скрипт while true do end завершается по TLWY, то pcall не гарантирует устойчивости. Потому-то и не запускаем. Как и скрипты в браузере. Но я понял твой подход. Игрокам, требовательным к стабильности работы компьютера, такие скрипты не нужны. Но остальным, возможно, пригодятся. Только надо честно предупреждать о возможных последствиях.
- 81 ответ
-
- 1
-
-
А каким образом внутри пользовательского кода OpenComputers можно реализовать механику TLWY? Насколько я понимаю, в лучшем случае можно убить скрипт по исчерпании доступного ему времени, заданного в конфигурации мода или перехватить совершаемые им вызовы. А в худшем случае лагающий сервер выключит комп раньше. А ещё можно получить бан от админа. И кроме стандартного while true do end можно придумать много других скриптов с тем же эффектом. Как предлагаешь бороться с ними?
- 81 ответ
-
- 1
-
-
Это условности, что называть сервером, а что клиентом. В контексте твоего чата клиентская часть отвечает за взаимодействие с пользователем, а серверная должна принимать сообщения даже при отключенной клиентской части.
-
Это далеко не кладезь. Синтетические тесты, конечно, полезны для понимания, но их практическая ценность не высока. Нужны какие-то примеры, приближенные к реальности: программа, долго считающая что-то нужное, которая после оптимизации начинает считать хотя бы в два раза быстрее. Предлагаю начать как раз с этой темы: рассказать, что такое оптимизация, зачем нужна, и как её применять, когда улучшение одного параметра ухудшает другой. И поправить противоречивые моменты, вводящие в заблуждение. Тогда этот урок будет давать какие-то ответы, а не порождать вопросы на ровном месте. Что значит "занимает"? В какой момент? В момент создания функции или на время вызова? Нужно ли вызывать сборщик мусора после вызова функции? Или сборщик мусора тут не поможет, и требуется очищать ссылку на функцию? Значит ли это, что избавление кода от функций всегда полезно для его производительности? Чему учит эта часть урока? Значит ли это, что очистка элементов таблиц не имеет смысла? А если я обнулил глобальную переменную, содержащую длинную строку, разве занимаемая ей память не будет очищена сборщиком мусора? И что значит, 10 раз подряд? Что мне мешает перемежать вызовы sleep какими-то вычислениями? И что мне мешает заменить вызовы sleep, вызовами методов периферии. И обязательно ли мне каждый раз делать ровно 10 вызовов, или есть способ определить факт вызова сборщика мусора? И как определить, что вообще пора его вызывать? Насколько чаще? Будет ли правильным вставлять сбор мусора в каждый вызов рекурсивной функции? Замыкание имеет чуть иной смысл. Возвращаемая функция должна использовать внешние по отношению к ней локальные переменные порождающей функции. Тогда будет замыкание. Здесь я не понял, что сейчас вообще было. Откуда надо удалить переменную , чтобы этот плюс нивелировался? И что за прирост даёт этот совет?
- 18 ответов
-
- lua 5.3
- opencomputers
-
(и ещё 1 )
Теги:
-
Пытаясь написать свою версию функции print(), я тоже интуитивно применил ipairs({...}). И т.к. функция предполагалась универсальной, я для теста подал в неё аргументы разных типов. В том числе и nil. На нём-то обработка и завершилась, хотя после nil были и другие аргументы. Я подсмотрел код print из openOS, и там обработка аргументов выглядит примерно так: function print(...) local args = table.pack(...) for i = 1, args.n do str = args[i] end end Решение показалось мне недостаточно красивым, и я попытался найти что-то более приятное глазу. Лучшего решения найти не удалось, но поиск привёл меня сюда. Полагаю, универсальное решение пригодится читателям этой темы.
-
Я неудачно задал вопрос. Он заключался в том, как далеко твой планшет находился от дрона в тот момент, когда программа просила подойти ближе.
- 52 ответа
-
- drone
- управление
-
(и ещё 1 )
Теги:
-
А на каком расстоянии от планшета до дрона просит подойти?
- 52 ответа
-
- drone
- управление
-
(и ещё 1 )
Теги:
-
Осталось лишь решить проблему шума. Интервалы времени длительностью 1.6629999990414e-06 вообще ни о чём не говорят на фоне шума измерений. Надо повторять эксперимент в цикле с достаточным количеством итераций. Например, для проверки одноразового вызова math.sin я бы использовал такие циклы: for i=1,1e6 do local sin = math.sin x = sin(3) end for i=1,1e6 do x = math.sin(3) end Но этого тоже недостаточно. Есть разброс значений. Поэтому надо повторять эксперимент какое-то количество раз. Какое именно? Надо вспоминать основы статистики. И если у кого-то эти воспоминания достаточно свежи, дайте совет. Для дальнейших рассуждений по теме я порылся в своих прошлых наработках, но оказалось, что там я застрял, не дойдя до конца. Но какая-то информация есть. Сервер нагружен неравномерно. И для выравнивания замеров имеет смысл чередовать циклы экспериментов: Выполнили в цикле один код, сделали короткую паузу, выполнили цикл со вторым кодом, сделал паузу, выполнили цикл с третим, и т.д., по кругу. Сервер бывает нагружен настолько неравномерно, что некоторые замеры аномально отличаются от среднего значения в болшьую сторону, и их надо бы отбрасывать. Мы же не характеристики сервера измеряем, а сравниваем эффективность кода. Но тут снова нужно аккуратно применять статистику. В своих прошлых экспериментах я пришёл к выводу, что итоговый код окажется достаточно сложным, что его проще будет вынести в отдельную библиотеку, аккуратно выполняющую замеры. Один я не готов оценивать глубину этой кроличьей норы, но @Taruu, мы можем попробовать написать такую библиотеку вместе. Также я прошу откликнуться и других форумчан. В тонкой сфере измерений аудит кода никогда не будет лишним. Также нужны идеи. Возможно, всё можно сделать проще, чем мне кажется. А я попробую в ближайшие дни найти все старые наработки и скомпилировать их во что-то определённое.
- 18 ответов
-
- 1
-
-
- lua 5.3
- opencomputers
-
(и ещё 1 )
Теги:
-
Да, здесь я ошибся. Обе операции не потребляют дополнительную память, но xor всё равно хуже по другим причинам. @LeshaInc своей картинкой, видимо, намекает на сложность темы, но это сразу было понятно. Тесты, измеряющие код, всегда сложно создавать, потому как кодомерка сама может вносить погрешность.
- 18 ответов
-
- lua 5.3
- opencomputers
-
(и ещё 1 )
Теги:
-
Пффф.. Ну, раз я влез в эту тему, то продолжу обсуждение. Не совсем. Как долго работает компьютер, скажет computer.uptime(), а os.clock() скажет, сколько из этого времени компьютер потратил на, собственно, вычисления. Конечно, с некоторыми оговорками, но в целом именно os.clock() позволяет оценить нагрузку, создаваемую тем или иным кодом на игровой сервер. Это грязный эксперимент с неправильной интерпретацией результата. В нём извлечение поля из таблицы выполняется два раза, о чём не упомянуто в описании. Также эксперимент не сообщает о том, имеет ли смысл создавать локальную переменную для функции math.sin, если её планируется использовать всего два раза. Или пять, например. Во всех экспериментах маловаты измеряемые интервалы времени. Но в этом они слишком малы. Шум легко может оказаться выше реальной разницы во времени. А шум есть всегда, даже при выполнении кода на оборудовании с избыточной мощностью. А здесь как раз именно шум не позволяет увидеть, что a,b = b,a имеет ровно ту же эффективность. Вообще, при интерпретации результатов следует сравнивать полученную разницу с шумовой, чтобы не делать преждевременных выводов. В этом месте я всё-таки ожидал увидеть экспериментальное подтверждение «эффективности» этого трюка. Но именно это заблуждение надо развеять в первую очередь. Эксперимент: local a,b = 23,76 local computer = require("computer") local mem0 = computer.freeMemory() for i=1,1e7 do a,b=b,a end print(mem0 - computer.freeMemory()) -- Результат: 0 for i=1,1e7 do a=a~b b=a~b a=a~b end print(mem0 - computer.freeMemory()) -- Результат: 6631 Результат: Обмен значений переменных через a,b=b,a потребляет ровно 0 дополнительной памяти и быстро работает. Зато обмен посредством XOR и память потребляет, и работает медленно, да ещё и код загромождает. Я не знаю, почему этот вредный совет транслируют на форумах программистов. Вне сомнений, в арсенале программиста должен быть трюк обмена переменных через исключающее или. Но зачем его тулить к месту и не к месту? Урок же вроде как про оптимизацию кода. И даже если бы этот трюк оказался эффективным, почему нет упоминания о том, что xor работает не для всех типов переменных? И раз пошёл такой разговор, разберу предыдущее обсуждение: Эффективнее со всех точек зрения. Lua для любых операций создаёт буферные переменные для хранения временных результатов. Но, в случае a,b=b,a они уничтожаются незамедлительно в отличие от xor. Операция a,b=b,aтребует на выполнение столько же времени, как три отдельных операции присваивания, но потребления памяти не увеличивает.
- 18 ответов
-
- 1
-
-
- lua 5.3
- opencomputers
-
(и ещё 1 )
Теги:
-
Изначально я не хотел комментировать этот «урок», т.к. объём комментариев в несколько раз превысил бы изначальный текст. Главная претензия к нему в отсутствии конкретики и каких-либо примеров, позволяющих читателю прийти к тем же выводам. @Taruu , приведя конкретный пример, спасает этот урок. Если кто-то хочет продолжить это начинание, я прошу не скидывать все замеры в одну программу, или хотя бы в коде одной программы дробить код на блоки и добавлять короткое описание, что именно там измеряется. Например, так: Демонстрация: локальная функция sin работает в два раза быстрее, чем функция math.sin. Замедление происходит два раза: при извлечении поля math из таблицы глобальных переменных и при извлечении поля sin из таблицы math. кусочек кода Также можно привести ещё пример, демонстрирующий, что работа с глобальной переменной равносильна работе с полем таблицы. А ещё важно продемонстрировать, начиная с какого числа использований становится выгодным копировать функцию math.sin в локальную переменную. Потому что если бездумно повторять советы из этого «урока», то вместо оптимизации может получиться пессимизация. Также я советую для записи чисел с большим количеством нулей использовать научную форму. Чтобы понять, сколько нулей содержит число 100000, мне приходится задерживать взгляд на этом числе, а запись 1e5 считывается мгновенно.
- 18 ответов
-
- 3
-
-
- lua 5.3
- opencomputers
-
(и ещё 1 )
Теги:
-
У меня тоже всегда соблюдалось, но документация не даёт гарантии, что так будет всегда. Условие n==6 никогда не выполнится.
-
@serafim , меня смущает этот кусок кода: print("пробный запуск") for i,n in pairs({3,2,4,5,0,1}) do red.setOutput(n, 15) if reactor.producesEnergy() then sideRed = n red.setOutput(sideRed, 0) print("реактор в стороне "..sideRed) os.sleep(1) break else red.setOutput(n, 0) end if n == 5 then print("\n".."реактор не запускается") os.exit() end end Во-первых, непонятно, зачем перебирать элементы массива вместо простого цикла for i=0,5 do. Возможно, здесь важен порядок перебора, но итератор pairs не гарантирует нужного порядка. Но даже если в определённой версии Lua порядок соблюдается, то последние два элемента никогда не будут обработаны, потому что цикл оборвётся по условию n==5.
-
Так, если в описании программы будет сказано, что она не будет правильно работать при использовании обшивки реактора. Обшивка реактора увеличивает теплоёмкость реактора. Поэтому при том же количестве тепла в реакторе его температура будет ниже. Но программа продолжит считать тепло вместо температуры.
- 13 ответов
-
- 1
-
-
- reactor
- opencomputers
-
(и ещё 2 )
Теги:
-
Не совсем так. Не текущая теплоёмкость, а текущее количество тепла getHeat(). А максимально возможное количество тепла getMaxHeat это и есть теплоёмкость реактора. Да, значения получаются маленькими в диапазоне от нуля до единицы включительно. Но если домножить на 100, то получим степень нагрева в процентах, если удобно работать с большими значениями. В Lua для подключения библиотек используется функция require. На форуме даже есть тема о создании библиотеки: Как создать библиотеку
- 13 ответов
-
- 1
-
-
- reactor
- opencomputers
-
(и ещё 2 )
Теги:
-
Да, в этой схеме нужен. Я невнимательно её рассмотрел. Привык к тому, что управляющий реактором компьютер питается от резервного энергохранителя на случай затухания реактора при нарушении поставок топлива. Обнаружилась ошибка: Почитав код, я заметил, что на самом деле проверяется не температура реактора, а количество тепла в нём, что нарушает задуманную логику. Для получения именно температуры потребуется разделить количество тепла в реакторе на теплоёмкость реактора: T = reactor.getHeat()/reactor.getMaxHeat(). Также код программы содержит два идентичных куска, меняющих цвет части картинки, и кусок, бессмысленно перерисовывающий неизменную часть картинки: while getHeat() >= 50 do gpu.setForeground(red) -- вывод фигуры треугольника ... gpu.setForeground(yellow) -- вывод фигуры огня и какой-то надписи ... computer.beep(500) os.sleep(1) gpu.setForeground(red) -- вывод фигуры огня и какой-то надписи ... computer.beep(500) os.sleep(1) end Чтобы не дублировать код вывода фигуры огня, и не перерисовывать на каждой итерации цикле фигуру треугольника, можно использовать такой код: gpu.setForeground(red) -- вывод фигуры треугольника ... local color = red while T >= 50 gpu.setForeground(color) -- вывод фигуры огня и какой-то надписи ... computer.beep(500) os.sleep(1) color = color==red and yellow or red end А вообще, вывод крупных кусков неизменного текста я рекомендую вынести в отдельные функции. На работу программы это существенным образом не повлияет, но поможет облегчить основную часть кода, отвечающую за логику, что упростит поиск ошибок.
- 13 ответов
-
- reactor
- opencomputers
-
(и ещё 2 )
Теги:
-
Первым делом хорошо бы добавить автоотключение реактора при аварийном отключении компьютера, что на перегруженных серверах случается часто. При использовании красного контроллера это невозможно, т.к. он сохраняет своё состояние независимо от состояния компьютера. Другое дело, красная плата, вставленная в компьютер: сигнал на её выходе автоматически пропадает при отключении компьютера (не программы), благодаря чему отключается и реактор. Но для реализации такой схемы потребуется установить компьютер вплотную к реактору. А рычаг-то зачем, если уже есть красный контроллер или красная плата, которые смогут осуществить не только все последующие запуски, но и первый тоже? И зачем в коде везде используется string.format, даже там, где отсутствуют переменные, вывод которых требуется форматировать? Чем больше лишних действий делает программа, тем вероятнее этот компьютер отключится на перегруженном сервере. А если он не успеет к этому моменту отключить красный контроллер, то можно потерять и реактор и свой домик.
- 13 ответов
-
- 1
-
-
- reactor
- opencomputers
-
(и ещё 2 )
Теги:
-
Поддержка есть, т.к. многие помнят этот мод. Возможно, помнят не так хорошо, как OpenComputers, но помнят. Для новичков сильным преимуществом ComputerCraft является его простота. Почти все из нас начинали с него. Но более опытные программисты ищут разнообразия, простота мода становится скучной для них. Поэтому многие переходят на OpenComputers. Компьютерные моды вообще не очень популярны в Майнкрафте. Тем не менее какая-то популярность имеется и у OpenComputers и у ComputerCraft.
-
Тогда, как выше сказал @BrightYC , поможет отладочная плата. А её можно воткнуть и в робота тоже.
-
Каких именно команд? С точки зрения программирования робот является компьютером, который имеет доступ к периферии робота. Логично, что робот может исполнять те же команды, что и компьютер.
-
@hohserg А что за компонент enderchest_1 присутствует в коде?
-
Принято делать так, как удобно автору приложений. Если приложение большое, то удобно создать для него отдельный репозиторий. Небольшие приложения, объединённые одной тематикой, бывает удобно хранить в одном репозитории. Это как с папками на компьютере. В одной папке можно хранить и сотню файлов. А иногда и ради трёх файлов удобнее создать отдельную папку. Насколько я помню, приватные репозитории на гитхабе доступны лишь платно. Но существует, например, гитлаб, не имеющий такого ограничения.
