Разница в скорости выполнения цикла увеличения и уменьшения
Я экспериментировал с циклами for, когда заметил, что простой цикл увеличения выполняется быстрее, чем цикл уменьшения. Я не могу придумать ни одной причины, почему это должно быть так. Есть ли что-то в моем коде, что вызывает различную скорость выполнения?
Код выглядит следующим образом:
// Глобальные переменные
const int spk = 7;
const int led = 6;
int j = 0; // переменная-счетчик
void setup() {
pinMode(spk, OUTPUT);
pinMode(led, OUTPUT);
Serial.begin(9600);
} // конец настройки
void loop() {
tone(spk, 300, 500); // первая нота с продолжительностью
// цикл увеличения
for (j=0; j <= 500; j = j + 1) {
digitalWrite(led, HIGH);
Serial.println(j);
} // конец цикла 1-й ноты
tone(spk, 100, 500); // вторая нота с длительностью
// цикл декремента
for (j = 500; j >= 0; j=j-1) {
digitalWrite(led, LOW);
Serial.print("the value is=");
Serial.print("\t");
Serial.println(j);
} // конец цикла 2-й ноты
} // конец настройки
@Zaffresky, 👍0
2 ответа
Лучший ответ:
Закомментируйте эти 2 строки
Serial.print("the value is=");
Serial.print("\t");
И сообщите о разнице в скорости. Почему бы не добавить чтение micros() до и после каждого цикла и посмотреть, насколько велика разница на самом деле? Все переменные времени имеют тип unsigned long.
startTime = micros();
// ваш цикл
endTime = micros();
duration = endTime - startTime;
Serial.println (" "); // Разрыв строки
Serial.print ("duration in uS = ");
Serial.println (duration);
Я отредактировал, добавив недостающие ) и второй разрыв строки.
В опубликованном вами коде цикл декремента содержит еще два оператора Serial.print().
Serial.print() занимает много времени, и хотя он полезен для отладки, иногда он может вызывать дополнительные ошибки из-за дополнительной задержки, которую он вносит, если вы запускаете код, чувствительный ко времени.
Рассмотрите возможность использования Serial.print("значение =\t" + itoa(j,10));
"itoa" преобразует целое число в массив символов (также известный как строка). Как сказал Юрадж, он принимает еще два аргумента: буфер для хранения выходной строки и базу, в которую он преобразует входящее число для представления (например: 10 — десятичное число, 16 — шестнадцатеричное). Он возвращает указатель на выходную строку, которая по существу совпадает со вторым аргументом, но AFAIR вы можете опустить второй аргумент и использовать его возвращаемое значение.
+
не объединяет массивы символов. itoa
имеет больше параметров, @Juraj
- Будет ли бесконечный цикл внутри loop() работать быстрее?
- Почему Serial.Write работает медленнее при записи x+1 символов, чем при записи x символов?
- Почему Arduino IDE долго открывается?
- Медленная частота обновления на экране I2C OLED
- Чтение квадратурного энкодера в реальном времени с полным разрешением только с одним прерыванием на ATmega328
- Arduino Nano работает очень медленно, хотя расчеты просты и задержек нет.
- Асимметричное шифрование на Teensy?
- Использование «static» с «RTClib»
Да, дополнительные серийные отпечатки в цикле декремента добавляли дополнительное время. Однако после добавления зеркал до и после каждого цикла и удаления всех дополнительных операторов печати я все еще обнаружил, что цикл декремента занимает на 60–80 микросекунд больше. Это обычно?, @Zaffresky
Я не знаю. Я не думаю, что когда-либо использовал декрементный цикл for:next. Также может быть что-то с установкой штифта на низкое или высокое значение. Вместо этого вы можете попробовать fastdigitalWrite(), посмотреть, имеет ли это значение (уже в IDE? Может быть, придется вытащить его из гутхаба?). Есть способ посмотреть на созданный ассемблерный код, посмотреть, что на самом деле запускается. Ник Гэммон публиковал такие примеры, не зная, как он вытащил сборку из процесса компиляции., @CrossRoads
Ах, все в порядке :) На самом деле это не имеет большого значения на данный момент. Идти после ассемблерного кода было бы слишком сложно, и я даже не знаю, как это сделать., @Zaffresky