Альтернативные реализации стандартных функций/подходов - страница 11

 
Nikolai Semko:
Сбросьте ссылочку пожалуйста 

Не сохранил. На форуме упоминал здесь. Сам искал через поисковики.

Вопрос к сообществу программистов по поводу авторства
Вопрос к сообществу программистов по поводу авторства
  • 2017.11.24
  • www.mql5.com
Общее обсуждение: Вопрос к сообществу программистов по поводу авторства
 
fxsaber:

Не сохранил. На форуме упоминал здесь. Сам искал через поисковики.

Я это видел. Там все очень примитивно без смешивания цветов пикселей.
Просто все,  что я встречал на форумах, был уровень детского сада. А я уже в 5м классе учусь.
 
Nikolai Semko:
Просто все,  что я встречал на форумах, был уровень детского сада. А я уже в 5м классе учусь.

Очевидно же, что все эти велосипеды много раз были когда-то пересобраны. Даже книжки выходили, вплоть до asm-реализаций.

Сейчас основы сложно найти, т.к. почти все используют соответствующие API на все случаи жизни.

Поэтому нужно просто регистрироваться на форумах и спрашивать.

 
fxsaber:

Очевидно же, что все эти велосипеды много раз были когда-то пересобраны. Даже книжки выходили, вплоть до asm-реализаций.

Сейчас основы сложно найти, т.к. почти все используют соответствующие API на все случаи жизни.

Поэтому нужно просто регистрироваться на форумах и спрашивать.

В том то и дело, что сложно. Во всяком случае я не смог найти. Возможно плохо искал. На форумах все будут посылать к стандартным закрытым библиотекам и недоумевать зачем это нужно, когда все есть. Понятное дело, я бы не парил себе мозг,  если писал бы на Java, JavaScript и т.п. , или если маркет был не нужен.
Ладно, я уже привык,  что в этом вопросе я пока в гордом одиночестве. Буду продолжать, тем более у меня практически нет белых пятен в понимании практически любой  реализаци в этом направлении. И зато приобрел уникальные навыки.
 
pavlick_:

А почему не пользуетесь LONG_MAX/MIN ? Будет как-то приличней смотреться. Вроде, ничего выглядит. Я прогал ваши тесты на gcc (c мин модификацией, естественно, компилятор очень старый 5.4.0, что было под рукой):


Ну да, не красиво. Но LONG_MAX = 9223372036854775807 больше, чем 9007199254740992. А на шестнадцатеричный вид этого числа - 0x‭20000000000000 ругается, т.к. он видимо только для типа ulong. Даже не знаю как сделать красивее. Не писать же (ulong)(1<<53), т.к. это уже операция, требующая времени.

Тип double начинает содержать в себе целые числа без дробной части не со значения  LONG_MAX, а с максимальной возможной мантиссы. А на мантиссу отведено 53 бита, т.е. 2^53=9007199254740992. 

pavlick_:

У вас в коде подсчёт времени барахлит - вывод в милисекундах (а не нано), и я так и не понял - зачем нужно минус t0.

t0 - это время полного цикла из 1000000 проходов суммы простых double

а t - время такого же цикла суммы тех же значений double, но пропущенных через функции ceil, Ceil, round  и т.д. 

Я исходил из логики, что разница (t-t0) и есть чистое время, затраченное именно на эти функции. 

Конечно же, большей объективности можно добиться только сделав несколько замеров.

- в нано я высчитываю исходя из времени выполнения одной функции из 1 000 000. Именно в нано правильно. 

pavlick_:

Я прогал ваши тесты на gcc (c мин модификацией, естественно, компилятор очень старый 5.4.0, что было под рукой):

1. Компиляция с -O3

2. Компиляция с -Ofast

Это что-ж получается. Что откомпилированный MQL5 код работает быстрее чем даже Ofast? С трудом верится.  Наверное там у Вас был 32 битный компилятор.
 
Nikolai Semko:

Не писать же (ulong)(1<<53), т.к. это уже операция, требующая времени.

Эта операция не требует времени, как все операции с константами, включая строки.

input long l = (ulong)1 << 53;
input string s = (string)__DATETIME__ + __FILE__;
 
fxsaber:

Эта операция не требует времени, как все операции с константами, включая строки.

Ух ты - прикольно! Спасибо. А я думал - каждый раз считает. Ну да логично, можно и на этапе компиляции уже посчитать.
Тогда так:

double Ceil (double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
2018.08.26 18:04:07.638 TestRound (EURUSD,M1)   Время цикла без округления = 1.302 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 18:04:07.642 TestRound (EURUSD,M1)   Время выполнения функции ceil =  2.389 наносекунд, Контрольная сумма = 1.15583114403606e+23
2018.08.26 18:04:07.644 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  0.223 наносекунд, Контрольная сумма = 1.15583114403606e+23
2018.08.26 18:04:07.648 TestRound (EURUSD,M1)   Время выполнения функции floor = 2.884 наносекунд, Контрольная сумма = 1.15583114403606e+23
2018.08.26 18:04:07.649 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.122 наносекунд, Контрольная сумма = 1.15583114403606e+23
2018.08.26 18:04:07.654 TestRound (EURUSD,M1)   Время выполнения функции round = 3.413 наносекунд, Контрольная сумма = 1.15583114403606e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.222 наносекунд, Контрольная сумма = 1.15583114403606e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

Правда было бы правильнее вместо 53 писать DBL_MANT_DIG

double Ceil (double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

Случай минимального выигрыша, если все значения double дробные.

2018.08.26 18:20:35.408 TestRound (EURUSD,M1)   Время выполнения функции sqrt = 1.083 наносекунд, сумма = 81969849.90928555
2018.08.26 18:20:35.413 TestRound (EURUSD,M1)   Время выполнения функции ceil =  3.579 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.416 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  1.249 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.422 TestRound (EURUSD,M1)   Время выполнения функции floor = 3.931 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.424 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.513 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.427 TestRound (EURUSD,M1)   Время выполнения функции round = 1.519 наносекунд, Контрольная сумма = 5249992896.0
2018.08.26 18:20:35.429 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.571 наносекунд, Контрольная сумма = 5249992896.0
Файлы:
TestRound.mq5  11 kb
 
Nikolai Semko:
Это что-ж получается. Что откомпилированный MQL5 код работает быстрее чем даже Ofast? С трудом верится.  Наверное там у Вас был 32 битный компилятор.

Я минус t0 отовсюду выкинул (подумал, что какая-то ошибка) и у меня в выводе замер всего цикла, а не одного прохода. Если привести к вашей форме вывода в наносекундах на итерацию (в первой строке "Время цикла без округления" - способ подсчёта у нас совпадает), то получим:

-O3
Время цикла без округления = 1.099 наносекунд, сумма = 1.15583114e+23
-Ofast
Время цикла без округления = 0.552 наносекунд, сумма = 1.15583114e+23

На gcc особого ускорения нет (а на -Ofast даже медленней). На мкл значительное судя по вашему тесту, но:

у вас 985'651 из 1'000'000 т.е. почти все итерации удовлетворяют условию x < MIN  || x > MAX.


-Ofast отключает всякие проверки на inf/nan, установку errno, т.е остаётся голое округление на fpu. И это голое округление не удаётся победить простейшим сравнением x < MIN  || x > MAX.

 
pavlick_:

На gcc особого ускорения нет (а на -Ofast даже медленней). На мкл значительное

Хотя как сказать. Для красивых цифр выкинули t0 и получили разнцицу в 20 раз. Даже минимальный дополнительный код в виде цикла (+t0) делает красивый результат в несколько десятков раз в менее привлекательный в районе двух раз. А чего говорить, если это не голый цикл, а реальный алгоритм делающий что-то полезное? Да разница вовсе будет не видна, будет болтаться где-то далеко после запятой и врядли станет узким местом. В реальном приложении взятие мьютекса, цпу барьеры, выделение памяти - гораздо более затратно, чем округление. В общем, имхо, не стоит игра свеч.

 
pavlick_:

Да разница вовсе будет не видна, будет болтаться где-то далеко после запятой и врядли станет узким местом. В реальном приложении взятие мьютекса, цпу барьеры, выделение памяти - гораздо более затратно, чем округление. В общем, имхо, не стоит игра свеч.

Это верно в 99% случаев, да.

Прежде, чем оптимизировать, стоит побеспокоиться, чтоб было, что оптимизировать.

На своей практике помню только один случай, когда реально помогла собственная реализация atof. Хотя казалось бы.

И стоит помнить о том, что любая оптимизация (кроме оптимизации ***) отнюдь не бесплатна.