PHP 数组性能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4904049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP array performance
提问by Ivan Vashchenko
I'm testing an algorithm for 2d bin packing and I've chosen PHP to mock it up as it's my bread-and-butter language nowadays.
我正在测试一种二维装箱算法,我选择了 PHP 来模拟它,因为它是我现在的基本语言。
As you can see on http://themworks.com/pack_v0.2/oopack.php?ol=1it works pretty well, but you need to wait around 10-20 seconds for 100 rectangles to pack. For some hard to handle sets it would hit the php's 30s runtime limit.
正如您在http://themworks.com/pack_v0.2/oopack.php?ol=1 上看到的那样,它运行良好,但您需要等待大约 10-20 秒才能打包 100 个矩形。对于一些难以处理的集合,它会达到 php 的 30 秒运行时限制。
I did some profiling and it shows that most of the time my script goes through different parts of a small 2d array with 0's and 1's in it. It either checks if certain cell equals to 0/1 or sets it to 0/1. It can do such operations million times and each times it takes few microseconds.
我做了一些分析,它表明我的脚本大部分时间都经过一个包含 0 和 1 的小型二维数组的不同部分。它要么检查某个单元格是否等于 0/1 或将其设置为 0/1。它可以执行数百万次这样的操作,每次只需要几微秒。
I guess I could use an array of booleans in a statically typed language and things would be faster. Or even make an array of 1 bit values. I'm thinking of converting the whole thing to some compiled language. Is PHP just not good for it?
我想我可以在静态类型语言中使用一组布尔值,事情会更快。或者甚至制作一个 1 位值的数组。我正在考虑将整个事情转换为某种编译语言。PHP 只是不适合它吗?
If I do need to convert it to let's say C++, how good are the automatic converters? My script is just a lot of for loops with basic arrays and objects manipulations.
如果我确实需要将它转换为 C++,那么自动转换器有多好?我的脚本只是很多带有基本数组和对象操作的 for 循环。
Edit. This function gets called more than any other. It reads few properties of a very simple object, and goes through a very small part of a smallish array to check if there's any element not equal to 0.
编辑。这个函数被调用的次数比其他任何函数都要多。它读取一个非常简单的对象的几个属性,并通过一个很小的数组的一小部分来检查是否有任何不等于 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;
}
Update: I've tried using 1d array instead of 2d as one of the answers suggested. Since I needed to always have current bin width accessible, I decided to wrap everything in the object. Also, now in every loop the index needs to be calculated. Now the script takes even more time to run. Other techniques didn't bring much performance boost, rather made code less readable. Time for HipHop I guess.
更新:我尝试使用 1d 数组而不是 2d 作为建议的答案之一。由于我需要始终可以访问当前的 bin 宽度,因此我决定将所有内容都包装在对象中。此外,现在在每个循环中都需要计算索引。现在脚本需要更多时间来运行。其他技术并没有带来太多的性能提升,反而降低了代码的可读性。我猜是 HipHop 的时候了。
Update: since hiphop php only runs on linux, and I don't have one, I've decided to rewrite the whole thing in C++. It's nice to freshen up the old skills. Also, if I do find a way to use hiphop, it'll be interesting to compare hand-written C++ code and the one hiphop would generate.
更新:因为 hiphop php 只在 linux 上运行,而我没有,我决定用 C++ 重写整个事情。更新旧技能是很好的。此外,如果我确实找到了一种使用 hiphop 的方法,比较手写的 C++ 代码和 hiphop 生成的代码会很有趣。
Update: I rewrote this thing in c++, on average it works 20 times faster and uses much less memory. Let me see if I can make it even faster.
更新:我用 C++ 重写了这个东西,平均它的运行速度快了 20 倍,并且使用的内存要少得多。让我看看我能不能让它更快。
采纳答案by NikiC
Array access in PHP can certainly be slow. PHP uses hash tables to implement arrays, i.e. in order to access an element in an array it has to calculate a hash and traverse a linked list. Using a compiled language with real arrays will definitely improve performance, because there a direct memory access is made. For the interested: Code for hash access with stringand with integer.
PHP 中的数组访问肯定会很慢。PHP 使用哈希表来实现数组,即为了访问数组中的元素,它必须计算哈希并遍历链表。使用带有真实数组的编译语言肯定会提高性能,因为可以直接访问内存。感兴趣的:使用 string和integer进行哈希访问的代码。
Concerning your code, there are several points I would optimize:
关于您的代码,我会优化以下几点:
return
directly, don'tbreak
twice.- put
$file->get_width()
and$file->get_height
into simple variables. I assume that the height or width doesn't change throughout the process. Remember: Functions in PHP are slow. Use a one-dimensional array, instead of nested arrays. You save one hash lookup per iteration that way.Actually a one-dimensional array is only marginally faster or even slightly slower. Comparison of several ways of saving the data concerning performance and memory usage.
return
直接,不要break
两次。- put
$file->get_width()
和$file->get_height
into 简单变量。我假设高度或宽度在整个过程中不会改变。请记住: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;
}
Though I'm not sure, why you add $x
to the $width
/ $y
to the $height
. Don't you want to iterate from the current coordinates to the image boundaries?
虽然我不知道,为什么你添加$x
到$width
/$y
到$height
。你不想从当前坐标迭代到图像边界吗?
回答by mario
The solution to your problem might be https://github.com/facebook/hiphop-php/wiki/
您的问题的解决方案可能是https://github.com/facebook/hiphop-php/wiki/
As said by everyone else, PHP is not the optimal language for calculation intensive tasks. It also doesn't really have an array type. What's described as array()
in PHP is really a dictionary / hash map. It has some optimizations to double as list, but as you've already discovered it doesn't provide the same runtime behaviour as C pointers and arrays.
正如其他人所说,PHP 不是计算密集型任务的最佳语言。它也没有真正的数组类型。array()
PHP 中所描述的实际上是一个字典/哈希映射。它有一些优化可以兼作列表,但正如您已经发现的那样,它不提供与 C 指针和数组相同的运行时行为。
HipHop can transform PHP code into optimized C++. It was targetted at string manipulation as well, but it could very well offer a proper array/list transformation.
HipHop 可以将 PHP 代码转换为优化的 C++。它也针对字符串操作,但它可以很好地提供适当的数组/列表转换。
Disclaimer: I've never tried it. Just wanted to contribute a smart sounding answer here.
免责声明:我从未尝试过。只是想在这里贡献一个聪明的听起来的答案。
回答by JamesHoux
UPDATED ANSWER NEEDED AS OF 2018.
截至 2018 年需要更新的答案。
This question is old and the answers given aren't completely true in PHP 7 ifyou use packed arrays. Because the question shows up first hit on google, I'm adding a new answer
这个问题很老,如果您使用压缩数组,那么在 PHP 7 中给出的答案并不完全正确。因为这个问题首先出现在谷歌上,所以我添加了一个新答案
If you use only integers as array keys in PHP 7 and make sure that you insert them into the array in ascending order, you can see improvements of 10x faster array operations.
如果在 PHP 7 中仅使用整数作为数组键并确保将它们按升序插入数组,则可以看到数组操作速度提高了 10 倍。
Read here: Blackfire Blog on PHP 7 Array Improvements
在这里阅读: 关于 PHP 7 数组改进的 Blackfire 博客
回答by edorian
To suggest another PHP alternative:
建议另一种 PHP 替代方案:
Have you looked into SplFixedArray
?
你调查过SplFixedArray
吗?
Depending on how your arrays are structured (linear 0 to x) arrays this can perform quite a bit faster
根据您的数组的结构(线性 0 到 x)数组,这可以执行得更快
For a benchmark see: http://www.slideshare.net/tobias382/new-spl-features-in-php-53Slide 15 & 16 (sorry, didn't find a better one)
有关基准测试,请参阅:http: //www.slideshare.net/tobias382/new-spl-features-in-php-53Slide 15 & 16(抱歉,没有找到更好的)
回答by Treffynnon
A more recent alternative is the QB extension to PHP that is specifically designed to help with this kind of problem.
最近的一个替代方案是 PHP 的 QB 扩展,它专门用于帮助解决此类问题。
While PHP is an excellent language for building complex web application, it imposes certain limitations. Writing code that performs low-level, computationally intensive tasks in PHP is generally impractical--it'd simply be too slow. The QB extension addresses this particular weakness of PHP. By translating Zend opcodes and executing them through a statically typed virtual machine, QB offers an order-of-magnitude gain in performance. The added power allows PHP programmers do things they were unable to do before, such a complex, pixel-level image manipulation.
虽然 PHP 是一种用于构建复杂 Web 应用程序的优秀语言,但它也有一定的局限性。在 PHP 中编写执行低级、计算密集型任务的代码通常是不切实际的——它只是太慢了。QB 扩展解决了 PHP 的这一特殊弱点。通过翻译 Zend 操作码并通过静态类型虚拟机执行它们,QB 提供了数量级的性能提升。增加的功能允许 PHP 程序员做他们以前无法做的事情,例如复杂的像素级图像处理。
See: http://php-qb.net/
回答by Erik B
Arrays in PHP indeed seem to be quite slow, especially looping through multidimensional arrays. Another option would be to try Quercus. It's an implementation of PHP in Java. I suppose it uses Java arrays. I haven't made a comparison though.
PHP 中的数组确实看起来很慢,尤其是在多维数组中循环。另一种选择是尝试Quercus。它是 PHP 在 Java 中的实现。我想它使用 Java 数组。不过我没有做过比较。
回答by Ondra ?i?ka
The question is nearly qualifiable as "primarily opinion-based". With that in mind:
这个问题几乎可以称为“主要基于意见”。考虑到这一点:
"Is PHP just not good for it?"
“难道 PHP 不适合它吗?”
PHP was originally just a web templating language, and simplicity was higher concern than performance when it was designed. It has evolved over time and many optimizations were added, but still, PHP's performance is relatively poor to the other platforms. So if your criteria is performance, then PHP is not good for it.
PHP 最初只是一种 Web 模板语言,在设计时,简单性比性能更受关注。它随着时间的推移不断发展,并添加了许多优化,但 PHP 的性能仍然相对于其他平台较差。因此,如果您的标准是性能,那么 PHP 并不适合它。
"I'm thinking of converting the whole thing to some compiled language."
“我正在考虑将整个内容转换为某种编译语言。”
Technically, can PHP also be compiled. There is a PHP to C++ compiler by Facebook. There is a just-in-time kind-of-compiler by Zend. There used to be a PHP on Java interpreter (although not active anymore if I remember correctly).
从技术上讲,PHP 也可以编译。Facebook 有一个 PHP 到 C++ 编译器。Zend 有一种即时编译器。曾经有一个关于 Java 解释器的 PHP(如果我没记错的话,虽然不再活跃了)。
I'd recommend you to try Java since it's syntax is similar, after all, it was one of PHP 5's inspirations. Java bytecode is compiled into native code since JDK 1.5. The performance should arise cca 4x for the same structure of code (assuming you use the community PHP distribution).
我建议您尝试 Java,因为它的语法相似,毕竟它是 PHP 5 的灵感之一。从 JDK 1.5 开始,Java 字节码被编译成本机代码。对于相同的代码结构,性能应该提高 4 倍(假设您使用社区 PHP 发行版)。