PHP函数效率

问题描述:

是否有表格显示在PHP中执行给定函数需要多少“工作量”?我不是一个综合专业,所以我也许没有正式的背景知道“哦,是的,字符串需要更长的时间来处理,而不是整数”或类似的东西。程序中的所有步骤/行是否都是平等的?我甚至不知道从哪里开始研究。PHP函数效率

我目前正在做一些项目欧拉问题,我很确定我的答案会起作用,但是我在一分钟内根据我的请求计时了我的本地Apache服务器(并且PE已经表示所有问题都可以解决< 1分钟)。我不知道如何/从哪里开始优化,所以了解更多关于PHP以及它如何使用内存将是有用的。对于它的价值,这是我为question 206代码:

<?php 
$start = time(); 
for ($i=1010374999; $i < 1421374999; $i++) { 
$a = number_format(pow($i,2),0,".",""); 
$c = preg_split('//', $a, -1, PREG_SPLIT_NO_EMPTY); 
if ($c[0]==1) { 
    if ($c[2]==2) { 
     if ($c[4]==3) { 
      if ($c[6]==4) { 
       if ($c[8]==5) { 
        if ($c[10]==6) { 
         if ($c[12]==7) { 
          if ($c[14]==8) { 
           if ($c[16]==9) { 
            if ($c[18]==0) { 
             echo $i; 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 
} 
$end = time(); 
$elapsed = ($end-$start); 
echo "<br />The time to calculate was $elapsed seconds"; 
?> 

如果这是关于优化维基问题,只是让我知道,我会移动。再次,没有寻找答案,只是帮助我了解在编码方面的高效性(尽管粗略的提示不会被拒绝,并且我意识到可能有更优雅的数学方法来设置问题)

+2

您最大的效率问题可能是您尝试暴力解决方案的事实。对于这些问题,没有任何代码可以使暴力解决方案发挥作用。没有太多的循环,你可以在一分钟内完成4.11亿次。而不是试图每秒钟挤压更多的迭代,试着将你所做的迭代次数减少几个数量级。 – 2009-06-28 22:34:56

+2

对于这个问题,你应该看看方形数字是如何工作的。例如mathworld.wolfram.com/SquareNumber.html。然后你会注意到,平方根的最后两位数字只能是30或70,这已经将你的搜索空间从4.11亿个数字减少到了8.220.000 – jitter 2009-06-28 23:19:42

有这么回事告诉你没有这样的表中的每个PHP多久函数需要执行,因为执行时间会根据输入而变化很大。

看看你的代码在做什么。你创建了一个将要运行411,000,000次的循环。鉴于代码需要在不到60秒(一分钟)内完成,为了解决这个问题,您假设每次通过循环的行程都将少于(大约).000000145秒。这是不合理的,没有任何数量的“正确”功能可以解决您的问题。试着用没有你的循环中有

for ($i=1010374999; $i < 1421374999; $i++) { 

} 

除非你有机会获得科幻小说的电脑,这可能不会在不到60秒的时间完成执行。所以你知道这种方法将永远不会工作。

这是众所周知的解决问题的蛮力解决方案。欧拉项目的目的是让你从数学和编程的角度创造性地思考问题。您想要减少您需要通过该循环的次数。显而易见的解决方案永远不会是这里的答案。

我不想告诉你解决方案,因为这些东西的重点是想你的方式,并成为一个更好的算法程序员。检查问题,考虑限制,考虑减少需要检查的总数。

采取看看执行时间为你的代码的好工具了XDebug:http://xdebug.org/docs/profiler

这是一个可安装PHP扩展,可配置为输出的函数调用和执行时间为您的脚本完全崩溃。使用这个,你将能够看到你的代码执行时间最长,并尝试一些不同的方法。

编辑:现在,我实际上在看你的代码,你正在运行4亿+正则表达式调用!我对欧拉项目一无所知,但我很难相信这些代码可以在商用硬件上在一分钟之内得到解决。

+0

他的代码不能不能解决他的问题。这就是这个欧拉项目的意义所在。数学问题,有可能写在一分钟内运行的求解器。 – jitter 2009-06-28 23:04:43

+0

我对它做了一些研究。正如在接受的答案中指出的那样,这看起来像一个有趣的项目。 – 2009-06-30 16:29:13

preg_split可能会很慢,因为它使用的是正则表达式。没有更好的方法来做那条线吗?

提示:您可以访问字符的字符串是这样的:

$str = 'This is a test.'; 
echo $str[0]; 
+0

这是一个很好的提示,谢谢 – 2009-06-28 22:23:10

尝试切换preg_split()explode()str_split()这是更快

首先,这里是你的函数的一个稍微干净版本,调试输出

<?php 
$start = time(); 
$min = (int)floor(sqrt(1020304050607080900)); 
$max = (int)ceil(sqrt(1929394959697989990)); 

for ($i=$min; $i < $max; $i++) { 
$c = $i * $i; 
echo $i, ' => ', $c, "\n"; 
if ($c[0]==1 
    && $c[2]==2 
     && $c[4]==3 
     && $c[6]==4 
     && $c[8]==5 
     && $c[10]==6 
     && $c[12]==7 
     && $c[14]==8 
     && $c[16]==9 
     && $c[18]==0) 
    { 
    echo $i; 
     break; 
    } 
} 
$end = time(); 
$elapsed = ($end-$start); 
echo "<br />The time to calculate was $elapsed seconds"; 

而这里的第一个10行输出:

1010101010 => 1020304050403020100 
1010101011 => 1020304052423222121 
1010101012 => 1020304054443424144 
1010101013 => 1020304056463626169 
1010101014 => 1020304058483828196 
1010101015 => 1020304060504030225 
1010101016 => 1020304062524232256 
1010101017 => 1020304064544434289 
1010101018 => 1020304066564636324 
1010101019 => 1020304068584838361 

也就是说,在那里,好像它现在应该激发您的算法可能的优化。请注意,我们甚至没有接近第六条目(1020304060504030225) - 我们有6个位置,我们需要5个位置!实际上,接下来的很多条目都是毫无价值的,直到我们回到了我们在那个位置上有5个位置的点。为什么要计算干预价值呢?如果我们能够找出如何,我们应该跳到1010101060,那个数字再次变成5 ......如果我们能够像这样一次跳过几十次迭代,那么我们将节省90%以上的运行时间!

请注意,这可能根本不是一种实用的方法(事实上,我相信它不是),但这是您应该思考的方式。你可以用什么数学技巧来减少你执行的迭代次数?