Часть1. Задача: найти способ самого быстрого переключения значений на пинах Iskra JS. Итак, проведем тесты пяти способов и засечем время за которое Iskra JS сможет включить и выключить 4 пина 1000 раз. Способ 1 примитивный Спойлер: способ 1 Код (Javascript): function test() { var cnt = 1000; var ft = Date.now(); for (var i=0;i<cnt;i++) { digitalWrite(P6, 1); digitalWrite(P6, 0); digitalWrite(P8, 1); digitalWrite(P8, 0); digitalWrite(P10, 1); digitalWrite(P10, 0); digitalWrite(P12, 1); digitalWrite(P12, 0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время выполнения: 773 мс ------------------------------------------ Способ 2 упаковка в массив http://www.espruino.com/Reference#l__global_digitalWrite Спойлер: способ 2 Код (Javascript): function test() { var cnt = 1000; var ft = Date.now(); for (var i=0;i<cnt;i++) { digitalWrite([P12,P12,P10,P10,P8,P8,P6,P6],0b01010101); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время выполнения: 437 мс Примечание: компиляция с использованием массива в digitalWrite на данный момент пока не поддерживается... ------------------------------------------ Способ 3 как и способ 1, но с предварительной компиляцией функции в нативный код с помощью строки "compiled"; https://www.espruino.com/Compilation Спойлер: способ 3 Код (Javascript): function test() { "compiled"; var cnt = 1000; var ft = Date.now(); for (var i=0;i<cnt;i++) { digitalWrite(P6, 1); digitalWrite(P6, 0); digitalWrite(P8, 1); digitalWrite(P8, 0); digitalWrite(P10, 1); digitalWrite(P10, 0); digitalWrite(P12, 1); digitalWrite(P12, 0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время выполнения: 338 мс ------------------------------------------ Способ 4 запись в регистры с помощью функции poke32. Внимание, использовать осторожно! http://www.espruino.com/Reference#l__global_poke32 Спойлер: способ 4 Код (Javascript): function test() { var pP6 = 0|P6.getInfo().out_addr; var pP8 = 0|P8.getInfo().out_addr; var pP10 = 0|P10.getInfo().out_addr; var pP12 = 0|P12.getInfo().out_addr; var cnt = 1000; var ft = Date.now(); for (var i=0;i<cnt;i++) { poke32(pP6, 1); poke32(pP6, 0); poke32(pP8, 1); poke32(pP8, 0); poke32(pP10, 1); poke32(pP10, 0); poke32(pP12, 1); poke32(pP12, 0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время выполнения: 659 мс ------------------------------------------ Способ 5 как и способ 4, но с предварительной компиляцией функции в нативный код с помощью строки "compiled"; https://www.espruino.com/Compilation Спойлер: способ 5 Код (Javascript): function test() { "compiled"; var pP6 = 0|P6.getInfo().out_addr; var pP8 = 0|P8.getInfo().out_addr; var pP10 = 0|P10.getInfo().out_addr; var pP12 = 0|P12.getInfo().out_addr; var cnt = 1000; var ft = Date.now(); for (var i=0;i<cnt;i++) { poke32(pP6, 1); poke32(pP6, 0); poke32(pP8, 1); poke32(pP8, 0); poke32(pP10, 1); poke32(pP10, 0); poke32(pP12, 1); poke32(pP12, 0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время выполнения: 0.62 мс = 620 мкс !!! ------------------------------------------ Я думаю, победителя представлять не надо P.S. Работоспособность проверялась с помощью пьезопищалки ака зуммер на P12 P.P.S. В данном опусе не учитываются некоторые способы оптимизации кода, о которых я напишу далее...
Часть 2. Хочу поделиться еще несколькими тонкостями по некоторой оптимизации кода, также позволяющей получить некоторый прирост скорости... И вообще советую прочитать заметки о производительности https://www.espruino.com/Performance , лично я подчерпнул от туда много полезного --------------------------------- Итак, начнем пожалуй со способа 1 из предыдущего поста. Его можно было ускорить, если не использовать в цикле длинные имена digitalWrite, а переопределить их с самого начала на что-нибудь короткое (всего из того же performance): Спойлер: способ 1 вариант 2 Код (Javascript): unction test() { var cnt = 1000; var ft = Date.now(); var d=digitalWrite; for (var i=0;i<cnt;i++) { d(P6, 1); d(P6, 0); d(P8, 1); d(P8, 0); d(P10, 1); d(P10, 0); d(P12, 1); d(P12, 0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время исполнения: 652 мс (на 121 мс быстрее оригинала) Этот же способ с компиляцей ( "compiled"; ): 208 мс (быстрее способа 3 на 130 мс) --------------------------------- Есть еще способ ускориться используя привязку https://www.espruino.com/Reference#l_Function_bind Спойлер: Способ с .bind() Код (Javascript): function test() { var cnt = 1000; var ft = Date.now(); var p1 = P6.write.bind(P6); var p2 = P8.write.bind(P8); var p3 = P10.write.bind(P10); var p4 = P12.write.bind(P12); for (var i=0;i<cnt;i++) { p1(1); p1(0); p2(1); p2(0); p3(1); p3(0); p4(1); p4(0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } start_test(); Время выполнения: 476 мс То же самое с компиляцей ( "compiled"; ): 126 мс (прирост в 350 мс) --------------------------------- Так же дает небольшой прирост в 20-30 мс явное определение режима работы пина pinMode() https://www.espruino.com/Reference#l__global_pinMode (используется в тестах), чтобы не заставлять работать автоматику. Проверить можно следующим кодом Спойлер: pinMode() Код (Javascript): function test() { "compiled"; var cnt = 1000; var ft = Date.now(); var p1 = P6.write.bind(P6); var p2 = P8.write.bind(P8); var p3 = P10.write.bind(P10); var p4 = P12.write.bind(P12); for (var i=0;i<cnt;i++) { p1(1); p1(0); p2(1); p2(0); p3(1); p3(0); p4(1); p4(0); } print(Date.now()-ft); } function start_test(){ pinMode(P6, "output"); pinMode(P8, "output"); pinMode(P10, "output"); pinMode(P12, "output"); test(); } test(); setTimeout('start_test()',1000);