C ++循环不断评估if语句,使其太慢

Posted

技术标签:

【中文标题】C ++循环不断评估if语句,使其太慢【英文标题】:C++ loops continually evaluating if statement, making it too slow 【发布时间】:2017-06-15 13:01:58 【问题描述】:

我目前有一个 C++ 程序,它应该生成每个可能的域名,最多达到一定的位数。我拥有的代码目前非常冗长(这很好),但一旦开始生成超过 4 位数字,它也会非常缓慢。真正开始出错的循环如下所示:

const char* chars[] = "a","b","c","d","e","f","g","h","i","j","k",
"l","m","n","o","p","q","r","s","t","u","v","w","x","y","z", "0", "1",
"2", "3", "4", "5", "6", "7", "8", "9", "-";
int char_num = 1;

[...]

if(char_num == 5) 
    for(int i = 0; i < 36; i++) 
      for(int j = 0; j < 37; j++) 
        for(int k = 0; k < 37; k++) 
          for(int l = 0; l < 37; l++) 
            for(int m = 0; m < 36; m++) 
              cout << "adding " << chars[i] << chars[j] << chars[k] << chars[l] << chars[m] << ".com to list\n";
              if(i == 35 && j == 36 && k == 36 && l == 36 && m == 35) 
                char_num++;
                cout << "Generating to " << char_num + 1  << " characters\n";
              
            
          
        
      
    
  

我打算在这个之后至少增加三个或四个额外的 if 语句,每个中都增加更多的 for 循环。我还需要将输出写入一个文件,并使用该文件进行 DNS 查找,所以我需要我可以获得的每一滴性能,所以我不需要等待数周才能完成程序。

我目前主要担心的是,考虑到嵌套循环的数量,我认为该程序正在评估每个交互的 if 语句,这对性能有显着影响。为了阻止这种情况,我尝试将 if 语句移动到一个单独的函数中,并让它在完成后返回一个值,但我注意到当我这样做时,我无法从函数内登录到控制台,这使得事情变得更多复杂。

在 C++ 中执行此操作的正确过程是什么?还有其他方法可以加快代码速度吗?我之前确实尝试在 node.js 中编写代码,但是当我开始写入文件时它变得疯狂并抛出了一堆内存不足的错误,而且我认为 C++ 可能会更快,因此我切换了语言。

【问题讨论】:

可能想看看这个:***.com/questions/35914946/… 评论你的cout &lt;&lt; "adding " ...,你会看到显示占用了所有的执行时间。所以我认为主要关心的是如何将数据有效地转储到一个文件或多个文件中。顺便说一句,你的 if 条件可以去掉。 条件会短路,所以if(i == 35) 将是整个测试,除非i 实际上 35。将int 值与常数进行比较,并且获得一致的结果,您将获得接近于零的成本。我们说的是现代 x86 上的纳秒。 需要完成 65646288 次迭代才能完成该过程,因为如果您在单循环中仅进行数学或逻辑运算,那么 CPU 几乎什么都不是。但正如之前的评论所说,你正在屏幕上打印,这个操作真的很耗时。 我明白,你不是故意的,但你会的。从一台计算机上运行它不会使它太苛刻。您可以从提供它们的服务中下载列表。刚刚用谷歌搜索了这个wwws.io它看起来不是免费的,但你会得到比扫描更多的数据。 【参考方案1】:

您的if 语句似乎正在检查循环是否结束。有一个简单的解决方案可以避免这种情况:删除if 并将代码放在循环之后!

但是,如果您需要添加更多依赖循环变量的ifs,我真的不知道如何优化它。 不要,然而,将它们放在一个函数中:调用函数的开销会减慢你的代码(并且优化编译器无论如何都会内联你的函数)。

您可以探索以下几种可能性:

使用多线程/多处理。如果做得好,这可以将执行时间除以计算机上的 CPU 内核数 启用编译器优化(-O3-Ofastg++

最后一件事:如果消费者程序接受来自标准输入的数据,则将程序的输出通过管道传输到它的速度将是生成名称的两倍然后。 EG而不是

producer > storage.txt
consumer < storage.txt

producer | consumer

【讨论】:

谢谢。这些都是有用的建议。我会尝试实施它们,看看它们是否有很大帮助。 在优化任何东西之前,我建议先了解为什么您的代码需要时间。然后你可以考虑多线程。【参考方案2】:

专注于代码优化。在语句中,您每次迭代都会不断地重新访问 char 数组的同一个成员,从而浪费时钟周期。

`cout << "adding " << chars[i] << chars[j] << chars[k] << chars[l] << chars[m] << ".com to list\n";`

一种优化方法是添加临时变量。

char tempI;
char tempJ;
char tempK;
char tempL;
if(char_num == 5) 
  for(int i = 0; i < 36; i++) 
    tempI = char[i];
      for(int j = 0; j < 37; j++) 
        tempJ = char[j];
          for(int k = 0; k < 37; k++) 
           tempK = char[k];
            for(int l = 0; l < 37; l++) 
             tempL = char[l];
              for(int m = 0; m < 36; m++) 
                cout << "adding " << tempI << tempJ << tempK << tempL << 
  chars[m] << ".com to list\n";
                if(i == 35 && j == 36 && k == 36 && l == 36 && m == 35) 
                char_num++;
                cout << "Generating to " << char_num + 1  << " characters\n";
              
            
          
        
      
    
  

您可以做一些事情来使您的代码在时间和空间局部性方面更快。

还将编译器优化 -03 与 g++ 等一起使用。

或者考虑重写你的算法,因为在时间复杂度方面可能有更好的方法

【讨论】:

以上是关于C ++循环不断评估if语句,使其太慢的主要内容,如果未能解决你的问题,请参考以下文章

C语言:if语句 一元二次方程

有对C语言熟悉的吗?我对if语句有点小小的疑问,请您解答。。

求一些C语言if嵌套语句算法题

C语言问题,我想的是if条件语句里三个都满足,但是只能满足两个,有啥办法解决,急,在线等?

C语言分支语句与循环语句

C语言基础