Прочитал тут про шаблонное программирование в C++ и задался целью проверить, насколько это позволяет эффективно переложить вычисления на компилятор. Написал простой код для Due: Код (C++): template <int n> struct Factorial { enum {value = n * Factorial<n-1>::value}; }; template<> struct Factorial<0> { enum {value = 1}; }; int factorial(int n) { if (n == 1) { return 1; } else { return n * factorial(n - 1); } } void setup() { // put your setup code here, to run once: Serial.begin(9600); while(!Serial) { // Do nothing } } void loop() { // put your main code here, to run repeatedly: int start_val = micros(); Serial.print("12! = "); Serial.println(Factorial<12>::value); int end_val = micros(); Serial.print("Loop1 time is: "); Serial.println(end_val - start_val); start_val = micros(); Serial.print("12! = "); int fact = factorial(12); Serial.println(fact); end_val = micros(); Serial.print("Loop2 time is: "); Serial.println(end_val - start_val); delay(10000); } По результатам, вычисление 12! (и отправка) с помощью шаблонов и с помощью функции занимает 35 и 37 микросекунд соответственно. Для 10! это 31 и 33 микросекунды. Больше 12! число не помещается в 32-битный int. Вопрос, это выигрыш от TMP такой мизерный или это я где-то ошибся? А может, компилятор слишком умный и функцию тоже заранее вычисляет?
Шаблоны ничего не вычисляют. Так близко оно только потому, что функция написана рекурсивно, что ужасно.
Вычисления проводит оптимизатор. Который в arduino ide выключен. Шаблоны можно использовать как средство для генерации легкооптимизируемого кода.
Мне кажется, вы не правы. Шаблоны же в этом коде как-то работают и результат получается правильный. Только выигрыша особо не заметно почему-то.
Можно и так, хотя это как микроскопом гвозди забивать.В вашем конкретном случае самым эффективным было бы заранее посчитать факториал 12 на калькуляторе и вписать готовую цифру в код как константу. Исполнялось бы быстрее и код короче. А вообще большинство программистов С++ используют шаблоны совсем не так
Ну это просто пример, самый примитивный. Но мне интересно, что же происходит в этом коде на самом деле и как объяснить отсутствие видимой разницы между двумя вариантами.
Sharles, посмотрите внимательнее свой код .Кто так меряет? Вы измеряете время вычисления + два вывода в сериал. Ваши результаты ни о чем. Оставьте внутри отсечки времени только вычисления, вывод в сериал сделайте позже
Код перекомпонуйте Код (C++): start_val = micros(); int fact = factorial(12); end_val = micros(); Serial.print("12! = "); Serial.println(fact); Serial.print("Loop2 time is: "); Serial.println(end_val - start_val); и для второго варианта так же. Тогда результаты будут иметь хоть какой-то смысл
Переделал код, как вы сказали, заодно вынес определение переменных из основного цикла и сделал их глобальными. Результаты получились другие: 2 и 3 мкс для шаблона и функции соответственно. Все равно для рекурсивной функции как-то слишком быстро, нет? Правда и факториал мелковат, но это же целых 10 умножений. Куда они пропали?