PHP数组性能

Iva*_*nko 36 php arrays performance

我正在测试一个2d bin包装的算法,我选择PHP来模拟它,因为它现在是我的面包和黄油语言.

正如您在http://themworks.com/pack_v0.2/oopack.php?ol=1上看到的那样,它运行良好,但您需要等待大约10-20秒才能打包100个矩形.对于一些难以处理的集合,它将达到php的30s运行时限制.

我做了一些分析,它表明大部分时间我的脚本经过一个小的2d数组的不同部分,其中包含0和1.它要么检查某个单元格是否等于0/1,要么将其设置为0/1.它可以进行数百万次这样的操作,每次都需要几微秒.

我想我可以使用静态类型语言中的一系列布尔值,事情会更快.甚至可以创建一个1位值的数组.我正在考虑将整个事物转换为某种编译语言.PHP对它不好吗?

如果我确实需要将其转换为C++,那么自动转换器有多好?我的脚本只是用于基本数组和对象操作的循环.

编辑.这个函数被调用比任何其他函数更多.它读取一个非常简单的对象的一些属性,并通过一个小数组的一小部分来检查是否有任何元素不等于0.

function fits($bin, $w, $h, $x, $y) {

    $w += $x;
    $h += $y;

    for ($i = $x; $i < $w; $i++) {

        for ($j = $y; $j < $h; $j++) {

            if ($bin[$i][$j] !== 0) {
                return false;
            }
        }
    }

    return true;    
}
Run Code Online (Sandbox Code Playgroud)

更新:我尝试使用1d数组而不是2d作为建议的答案之一.由于我需要始终可以访问当前的bin宽度,因此我决定将所有内容包装在对象中.此外,现在在每个循环中都需要计算索引.现在脚本需要更多时间来运行.其他技术并没有带来太多的性能提升,而是使代码的可读性降低.我猜是时候嘻哈了.

更新:既然hiphop php只在linux上运行,而我没有,我决定用C++重写整个内容.刷新旧技能真好.另外,如果我找到了使用hiphop的方法,那么比较手写的C++代码和hiphop会产生的代码将会很有趣.

更新:我用c ++重写了这个东西,平均来说它的工作速度提高了20倍,并且使用的内存更少.让我看看我能否做得更快.

Nik*_*kiC 25

PHP中的数组访问肯定会很慢.PHP使用哈希表来实现数组,即为了访问数组中的元素,它必须计算哈希并遍历链表.使用带有实数阵列的编译语言肯定会提高性能,因为可以直接访问内存.感兴趣的:使用字符串整数进行散列访问的代码.

关于你的代码,我会优化几点:

  • return直接,不要break两次.
  • $file->get_width()$file->get_height成简单的变量.我假设在整个过程中高度或宽度不会改变.请记住:PHP中的函数很慢.
  • 使用一维数组,而不是嵌套数组.您可以通过这种方式每次迭代保存一个哈希查找.实际上,一维数组仅略微更快或甚至稍慢.保存有关性能和内存使用情况的数据的几种方法的比较.

.

function fits($bin, $x, $y, $w, $h) {
    $w += $x;
    $h += $y;

    for ($i = $x; $i < $w; ++$i) {
        for ($j = $y; $j < $h; ++$j) {
            if ($bin[$i][$j] !== 0) {
                return false;
            }
        } 
    }

    return true;   
}
Run Code Online (Sandbox Code Playgroud)

虽然我不知道,为什么你添加$x$width/ $y$height.您不想从当前坐标迭代到图像边界吗?

  • 与往常一样,我会很感激对downvote的解释. (6认同)
  • @Orbling:我检查了lxr,发现对于顺序数值数组,仍然使用哈希表.显然,如果索引是数字的,有几种简化,例如,不需要计算散列,而只需要应用表掩码.当遍历链表时,显然检查更简单,因为比较数字而不是字符串.但基本上它以相同的方式运作.它仍然是哈希表查找,有一些优化,但仍然是哈希表查找.它不像C中的直接内存访问. (2认同)
  • PHP7 修复阵列性能。如果您使用 PHP 7 打包数组(键必须仅为整数并按升序出现的数组),性能可以提高 10 倍。压缩数组的行为类似于真正的数组,而不是慢速哈希表。 (2认同)

mar*_*rio 11

您的问题的解决方案可能是https://github.com/facebook/hiphop-php/wiki/

正如其他人所说,PHP不是计算密集型任务的最佳语言.它也没有真正的数组类型.array()在PHP中描述的实际上是字典/哈希映射.它有一些优化可以加倍作为列表,但正如您已经发现它不提供与C指针和数组相同的运行时行为.

HipHop可以将PHP代码转换为优化的C++.它也是针对字符串操作的,但它可以很好地提供正确的数组/列表转换.

免责声明:我从未尝试过.只是想在这里贡献一个聪明的声音答案.


edo*_*ian 6

建议另一个PHP替代方案:

你看过了SplFixedArray吗?

根据数组的结构(线性0到x)数组,这可以更快地执行

有关基准测试,请参阅:http://www.slideshare.net/tobias382/new-spl-features-in-php-53幻灯片15和16(对不起,没找到更好的)


Jam*_*oux 5

截至2018年需要更新的答案。

这个问题很旧,如果使用压缩数组,给出的答案在PHP 7中并不完全正确。由于该问题显示在Google的第一击中,因此我添加了一个新答案

如果在PHP 7中仅将整数用作数组键,并确保将它们按升序插入到数组中,则可以看到数组操作速度提高了10倍。

在这里阅读: 有关PHP 7阵列改进的Blackfire博客