标准功能/方法的其他实现方式 - 页 11

 
Nikolai Semko:
能否请你把链接发给我?

没有保留它。在这里的 论坛上提到过。我自己通过搜索引擎看了一下。

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

没有保留它。在这里的 论坛上提到过。自己通过搜索引擎搜索了一下。

我已经看到了。没有像素色彩混合,这一切都非常原始。
只是我在论坛上遇到的所有东西都是幼儿园水平。而我已经是五年级的学生了。
 
Nikolai Semko:
只是,我在论坛上遇到的所有事情都是幼儿园水平的。而我已经是五年级的学生了。

很明显,所有这些自行车都已经被改造过多次了。甚至还出版了书籍,一直到asm的实现。

现在基本的东西很难找到,因为几乎所有人都在各种场合使用相关的API。

因此,你只需在论坛上注册并四处询问。

 
fxsaber:

很明显,所有这些自行车都已经被改造过多次了。甚至还出版了书籍,直到并包括asm实现。

现在,基本的东西很难找到,因为几乎每个人都在各种场合使用相关的API。

所以你只需在论坛上注册并询问。

这就是问题所在:这很难。总之,我没能找到它。也许我看得不够仔细。在论坛上,每个人都会把你送到标准的封闭库,并想知道为什么你需要它,因为一切都可以得到。当然,如果我用Java、JavaScript之类的语言写作,我也不会担心自己的脑袋。或如果市场不需要。
好吧,我已经习惯了在这件事上骄傲地独自一人,现在。我继续说,此外,在这个方向上,我对几乎任何实施的理解几乎没有空白点。而另一方面,我也获得了一些独特的技能。
 
pavlick_:

你为什么不使用LONG_MAX/MIN?这在某种程度上会看起来更漂亮。我想,它看起来不错。我已经用gcc做了你的测试(当然,只做了很少的修改,编译器是非常老的5.4.0,我手头的东西)。


嗯,是的,这不是很好。但LONG_MAX= 9223372036854775807比9007199254740992多。而这个数字的十六进制形式--0x20000000000000被呵斥,因为它必须只用于ulong类型。我甚至不知道该如何说得更清楚。我不能写(ulong)(1<<53),因为这是个耗时的操作。

double类型开始包含没有小数部分的整数,不是从LONG_MAX 值开始,而是从可能的最大尾数开始。但尾数允许有53位,即2^53=9007199254740992。

pavlick_

你的代码计时失败--输出单位是毫秒(而不是纳米),我还是不明白为什么我们需要减去t0。

t0是质数双数之和1000000次的全周期时间。

而t是相同周期的相同双值之和的时间,但通过函数ceil, ceil, round等传递。

我的逻辑是,差额(t-t0)是花在这些功能上的净时间。

当然,只有通过多次测量才能实现更多的客观性。

- 在纳米领域,我的计算基础是执行100万个功能中的一个功能所需的时间。确切地说,在纳米级是正确的。

pavlick_

我在gcc上运行了你的测试(当然,做了一些小的修改,编译器是非常老的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.15583114403606 e+23
2018.08.26 18:04:07.644 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  0.223 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.648 TestRound (EURUSD,M1)   Время выполнения функции floor = 2.884 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.649 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.122 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.654 TestRound (EURUSD,M1)   Время выполнения функции round = 3.413 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.222 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

然而,写成DBL_MANT_DIG 而不是53更正确。

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);}

如果双数的所有值都是小数,则收益最小的情况。

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.15583114 e+23
-Ofast
Время цикла без округления = 0.552 наносекунд, сумма = 1.15583114 e+23

在gcc上没有什么加速(在-Ofast上更慢)。从你的测试来看,在mcc上有明显的速度提升,但是。

你有985'651个1'000'000,也就是说,几乎所有的迭代都满足x < MIN || x > MAX的条件。


-Ofast禁用所有inf/nan检查,errno设置,即留下fpu上的裸奔。而且这种裸露的四舍五入不能被简单的比较x < MIN || x > MAX所打败。

 
pavlick_:

在gcc上没有什么加速(在-Ofast上更慢)。在µl上,它是显著的。

然而,这很难说。我们抛出了T0的漂亮数字,得到了20倍的差价。即使是以循环(+t0)形式出现的最小的额外代码,也会使美丽的结果在几十倍的范围内变得不那么吸引人,大约是2倍。而如果它不只是一个循环,而是一个真正的算法,做一些有用的事情,你能说什么?差异根本不明显,它将挂在小数点后很远的地方,很难成为瓶颈。在实际应用中,互斥区的拾取、CPU障碍、内存分配 的成本比四舍五入要高得多。总而言之,这不值得赌博,我认为。

 
pavlick_:

是的,差异根本不明显,会挂在小数点后很远的地方,不太可能成为一个瓶颈。在实际应用中,使用mutex、cpu障碍、内存分配 的成本比四舍五入要高得多。总而言之,这不值得赌博,我认为。

这在99%的情况下是真的,是的。

在优化之前,你应该确保你有东西 要优化。

在我的实践中,我只记得有一个案例,我自己实施的atof真的有帮助。尽管在我看来,它确实如此。

而且你应该牢记,任何优化(除了***)都不是免费的。