PHP 数组性能

2022-08-30 12:43:46

我正在测试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++,那么自动转换器有多好?我的脚本只是很多具有基本数组和对象操作的for循环。

编辑。此函数的调用次数比其他任何函数都多。它读取非常简单对象的几个属性,并遍历一个小数组的一小部分,以检查是否存在任何不等于 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;    
}

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

更新:由于嘻哈php只能在linux上运行,而我没有,我决定用C++重写整个东西。刷新旧技能是件好事。另外,如果我确实找到了一种使用嘻哈的方法,那么比较手写的C++代码和嘻哈会生成的代码会很有趣。

更新:我用c ++重写了这个东西,平均而言,它的工作速度提高了20倍,使用的内存要少得多。让我看看我是否能让它更快。


答案 1

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

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

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

.

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

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


答案 2

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

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

HipHop可以将PHP代码转换为优化的C++。它也以字符串操作为目标,但它可以很好地提供适当的数组/列表转换。

免责声明:我从未尝试过。只是想在这里贡献一个听起来很聪明的答案。