Особенности языка mql5, тонкости и приёмы работы - страница 117
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Вот родился у меня такой вариант:
По идее, это самый быстрый из всех возможных. Все вычисления производятся с константами, поэтому рассчитываются при компиляции. Итого, всё сводится лишь к 6 последовательным сравнениям, и ничего более. Однако, этот вариант у меня работает медленнее, чем предыдущий. Не могу понять, в чём причина.
Вот родился у меня такой вариант:
По идее, это самый быстрый из всех возможных. Все вычисления производятся с константами, поэтому рассчитываются при компиляции. Итого, всё сводится лишь к 6 последовательным сравнениям, и ничего более. Однако, этот вариант у меня работает медленнее, чем предыдущий. Не могу понять, в чём причина.
Деление на два замедляет ? Попробовать заменить сдвигом ? Подозрение, что вычисляемые константы - надо вычислять сразу (в этом случае - и сдвиг в дефайне - также надо заменить константой).
Кроме того - "вопросик" - как я знаю, это довольно спорный оператор, когда-то, двадцать лет назад проверяли на С++, иногда "вопросик" генерирует более длинный код, чем обычный оператор if. Может и здесь так ?
И, я бы сделал код возврата uint - вдруг там какие-то проверки идут при преобразовании знаковых и беззнаковых величин ?
Пока нет возможности поэксперементировать самому - процессор загружен под завязку... Даже текст набирается "с пробуксовками"...
Деление на два замедляет ? Попробовать заменить сдвигом ? Подозрение, что вычисляемые константы - надо вычислять сразу (в этом случае - и сдвиг в дефайне - также надо заменить константой).
Кроме того - "вопросик" - как я знаю, это довольно спорный оператор ...
Замена деления сдвигом не влияет. Я подозреваю, что получающееся выражение слишком длинное, поэтому компилятор его не оптимизировал до конца.
Однако это я проводил тесты при Optimize=0. А при включении оптимизации всё встало на свои места: второй вариант быстрее примерно в полтора раза. Бинго!
Если же оптимизация отключена, то второй вариант чуть медленнее при небольших значениях, но чуть быстрее при больших. Короче говоря, второй вариант определённо лучше.
Вот родился у меня такой вариант:
По идее, это самый быстрый из всех возможных. Все вычисления производятся с константами, поэтому рассчитываются при компиляции. Итого, всё сводится лишь к 6 последовательным сравнениям, и ничего более. Однако, этот вариант у меня работает медленнее, чем предыдущий. Не могу понять, в чём причина.
Все верно - Ваш вариант самый быстрый.
Просто тест холостой. Очень часто при тесте на производительность забывают один важный момент: если вычисляемое значение нигде не используется, то компилятор просто напросто не производит вычисления.
Ведь это логично - какой смысл? Это как в квантовой суперпозиции. Зачен существовать луне, если на нее никто не смотрит. "Неужели Луна существует только потому, что на нее смотрит мышь?" (Альберт Эйнштейн). :))
Поэтому такой вариант теста с вычислением контрольной суммы и печати её будет правильнее:
Результат:
А второе место все же _FastLog2, а не log2 :))Просто тест холостой. Очень часто при тесте на производительность забывают один важный момент: если вычисляемое значение нигде не используется, то компилятор просто напросто не производит вычисления.
Ведь это логично - какой смысл? Это как в квантовой суперпозиции. Зачен существовать луне, если на нее никто не смотрит. "Неужели Луна существует только потому, что на нее смотрит мышь?" (Альберт Эйнштейн). :))
Поэтому такой вариант теста с вычислением контрольной суммы и печати её будет правильнее:
Ваш код запутанный. Переменные, используемые в дефайне, расположены в другом конце кода программы - неудобно разбираться в таком хаосе. Но суть не в этом, а в том, что результаты ваших тестов нельзя считать достоверными, т.к. компилятор заранее знает алгоритм значений, передаваемых в функцию. Поэтому он оптимизирует ваши тесты. Нужно рассчитывать на случайных числах.
Кстати, зачем у вас srand в коде? Я, увидев его, сначала и подумал, что у вас используется рандом, но по факту - нет.
Вот мой код:
Ваш код запутанный. Переменные, используемые в дефайне, расположены в другом конце кода программы - неудобно разбираться в таком хаосе. Но суть не в этом, а в том, что результаты ваших тестов нельзя считать достоверными, т.к. компилятор заранее знает алгоритм значений, передаваемых в функцию. Поэтому он оптимизирует ваши тесты. Нужно рассчитывать на случайных числах.
Кстати, зачем у вас srand в коде? Я, увидев его, сначала и подумал, что у вас используется рандом, но по факту - нет.
Вот мой код:
код не мой. Я лишь его подправил и выкинул rand, чтобы проверить одинаковость контрольных сумм и убрать из цикла относительно затратные функции rand, а srand просто забыл выкинуть.
Возвращаю rand. Вы правы - компилятор действительно оптимизирует цикл суммы логарифмов из последовательных значений. Хотя я удивлен. Не понимаю, как он это делает. Возможно, что-то мы не учитываем.
Результат:
Текущий победитель _FastLog2
Результат:
Текущий победитель _FastLog2
Интересно, каким образом у вас получилась везде одинаковая контрольная сумма, если значения рандомные.
Интересно, каким образом у вас получилась везде одинаковая контрольная сумма, если значения рандомные.
srand(45) для всех функций
просто сначала тоже так сделал, но получил разные контрольные суммы, т.к. не учел что rand()*rand() может быть 0, а это ломает контрольную сумму. Сейчас добавил единицу, чтобы уйти от нуля.
srand(45) для всех функций
просто сначала тоже так сделал, но получил разные контрольные суммы, т.к. не учел что rand()*rand() может быть 0, а это ломает контрольную сумму. Сейчас добавил единицу, чтобы уйти от нуля.
А зачем вам одинаковая контрольная сумма, если речь идёт конкретно о замере скорости? Суть суммы в этом случае - просто не дать компилятору вырезать код, вот и всё. А делая srand(45), вы опять-таки позволяете оптимизировать тест.
Кстати, по поводу нуля. В FastLog2 нет проверки на нуль, это соответственно и фору ему даёт. Но он всё-равно в полтора-два раза медленнее, чем log2, если тестировать корректно )
А зачем вам одинаковая контрольная сумма, если речь идёт конкретно о замере скорости? Суть суммы в этом случае - просто не дать компилятору вырезать код, вот и всё. А делая srand(45), вы опять-таки позволяете оптимизировать тест.
Здесь Вы переоцениваете возможности компилятора. Уберите srand(45) - контрольные суммы станут разными, но результат скорости сохраниться.
Тем более я руководствовался тем, чтобы вычисления были одинаковыми для чистоты эксперимента, т.к. не вдавался в подробности всех функций. Иногда значение параметра функции могут влиять на время её выполнения.
Тем более заодно проверить правильность алгоритмов.