MQL5中的OOP问题 - 页 65

 
Sergey Dzyublik:

你忘记了一些关于结构和类的事情(没有新的)--它们都在堆栈上很突出。

不要与C++混淆,它更接近于夏普。

 
Maxim Kuznetsov:

不要与C++混淆,它更接近于夏普。

这是你的幻想,不是现实。
你不应该证明你自己没有测试过的东西......
创建局部变量作为结构和类的对象(没有new)发生在堆栈上。
我之前描述了 数组在MT5中的工作原理

 
Dmitry Fedoseev:

多么无奈啊!

1 - 通过对象创建。2 - 简单地通过一个正常的函数调用。第一个数字是以毫秒为单位的时间,不要注意第二个数字。

它几乎快了10倍(有时甚至超过10倍)。多么可悲的事情...堆积......堆积......。***cha

那么,为什么不注意呢?让我猜猜看:INT_MAX曾经通过创建一个临时对象执行了一个动作,然后又通过一个函数调用执行了同样的动作?

嗯,这是一个预期的结果,考虑到我们仍然在运行时创建类的过程中跳舞(我们仍然应该得到这个句柄,它看起来像某个容器中的索引)。

PS。回放的源代码在哪里?

PPS。你确定该函数被调用了吗?总之,优化器也在这段代码中,而不是在运行时将有一个函数调用的事实。

for (int i=0;i<500;++i){
   int x=Get(i);}

int Get(int x) {return -x;}

mql中的UB存在的事实--证明了这个代码。

void OnStart(){
   Print(Test()?"Ok":"No");
}

bool Test (void)
{
  const int MAX = 1000;
  int a=1,b=1,c=1;
  while (1) {
    if (((a*a*a) == ((b*b*b)+(c*c*c)))) return true;
    a++;
    int x=Get(a);
    if (a>MAX) {
      a=1;
      b++;
    }
    if (b>MAX) {
      b=1;
      c++;
    }      
    if (c>MAX) {
      c=1;
    }
  }
  return false;
}
 
Vladimir Simakov:

mql有UB的事实证明了这个代码。

你巧妙地将编译器缠绕在你的手指上:
- false分支被抛出,因为没有从while(1)循环中断开。
- true被返回,因为操作是在本地变量 上进行的,与 "外部世界 "没有任何互动,执行这段代码也被抛出。

 
Sergey Dzyublik:

你巧妙地把编译器包在你的手指上:
- 假分支被抛出,因为没有从while(1)循环中断开。
- true被返回,因为操作是在本地变量 上进行的,与 "外部世界 "没有任何互动,执行这段代码也被抛出。

这不是我--是互联网上的一个例子。这一点和优点是一样的。

 
Vladimir Simakov:

为什么不注意呢?让我猜猜看:INT_MAX曾经通过创建一个临时对象执行了一个动作,然后又通过函数调用执行了同样的动作?

总而言之,这是一个预期的结果,考虑到我们仍然在随机化的类的创建中跳舞(我们应该得到这个句柄,它看起来像某个容器中的索引)。

PS。回放的源代码在哪里?

PPS。你确定该函数被调用了吗?总之,优化器也在这段代码中,而不是在运行时将有一个函数调用的事实。

UB在mql中的事实证明了这个代码。

你错了。你不必在这里猜测,只需记住昨天,在记忆有问题的情况下,你可以通过引语来看看讨论的内容。既然之前你宣称的结果是相反的,为什么突然变成了预期的结果呢?

是的,我肯定这个函数被调用了。而你们都喜欢梦想我是个白痴?为什么问题只涉及函数,而对象可能也没有被创建?还是你很确定你知道所有编译器的工作原理?

 
Sergey Dzyublik:

你能解释一下这是怎么回事吗?因为我有点笨,我已经读了三遍--但我还是不明白......

看看这些引文,看看我们在说什么。我所引用的,也是针对我从引用中得到的这个回应。

 
和你的每一次谈话都变成了这样的废话......关于堆栈,关于阵列字符串...你通过 "在堆栈中 "的解释并不奏效。
 

由于Dimitri不好意思公布他的代码,我不得不自己做15分钟的测试。

哎呀。在相同的操作下,差异只有30%。

class CTest{
   static uint count;
   static double temp;
   int i;
public:
   CTest(int _x):i(_x){++count; temp+=(double)GetMicrosecondCount(); temp/=count;}
   ulong Get() {return GetMicrosecondCount()+i;}
   static uint Count()  {return count;}
   static double Temp() {return temp;}
};

int i=1;
double temp;

uint CTest::count=0;
double CTest::temp=0.0;

void OnStart(){
   ulong t=GetMicrosecondCount();
   for (;i<1000001;++i){
      temp+=(double)CTest(i).Get();
      temp/=i;}
   ulong _t=GetMicrosecondCount()-t;
   Print(_t," | ",i);
   Print(CTest::Count());
   Print(CTest::Temp());
   t=GetMicrosecondCount();
   for (;i<2000001;++i){
      temp+=(double)Test(i);
      temp/=i;}
   _t=GetMicrosecondCount()-t;
   Print(_t," | ",i);
   Print(temp);
}

ulong Test(int x) {
   static uint count=0;
   static double _temp=0.0;
   ++count;
   _temp+=(double)GetMicrosecondCount();
   _temp/=count;
   return GetMicrosecondCount()+x;}

即使没有静态变量 和字段的这些麻烦,运行时的差异仍然存在。这是以微秒为单位的差异,而不是百分比。

结论:在我的不是最快的电脑上,在堆栈上创建一个临时对象的成本很小,大约是30-40ns/pc(纳秒),所以在大多数情况下我应该注意它。

PS。而我对开发者的想法很糟糕,但不,你就是不需要听别人的话,也不需要检查他们)))。

 
Vladimir Simakov:

由于Dimitri不好意思公布他的代码,我不得不自己做15分钟的测试。

哎呀。在相同的操作下,差异只有30%。

即使没有静态变量 和字段的这些麻烦,运行时的差异仍然存在。这是以微秒为单位的差异,而不是百分比。

结论:在我的不是最快的电脑上,在堆栈上创建一个临时对象的成本很小,大约是30-40ns/pc(纳秒),所以在大多数情况下我应该注意它。

PS。而我对开发者的想法很糟糕,但没有,你就是不相信别人的话,也要检查他们)))。

更有甚者在里面做各种不同的计算,差别会更小。无论如何,这个测试很难被称为相同功能的测试。

此外,这些测试本身并不完全相同。