php - 在 PHP 中访问大数组

标签 php arrays performance

我一直在对在 PHP 中访问大型(左右)数据数组的不同方法进行一些分析。用例非常简单:我们的一些工具将数据作为关联数组输出到 PHP 文件中,这些文件被应用程序视为静态数据。我们制作游戏,因此数据文件的一些示例包括目录中的项目、用户必须完成的任务或 map 的定义:

<?php
$some_data = array(
    ...lots and lots of stuff in here...
);
?>

由于这些数组很大 (400K),而且我们的大部分代码都对这些数据感兴趣,因此有必要尽可能高效地访问这些数据。我决定用 3 种不同的模式来做这件事。介绍完这些方法后,我将在下面分享我的结果。

我正在寻找的是对这些方法及其时间以及任何其他尝试方法的基于经验的验证。

方法#1:吸气函数

在该方法中,导出器实际上创建了一个如下所示的文件:

<?php
function getSomeData()
{
    $some_data = array(
        ...lots and lots of stuff here...
    );
    return $some_data;
}
?>

然后,客户端代码可以在需要时通过简单地调用 getSomeData() 来获取数据。

方法#2:全局+包含

在这种方法中,数据文件看起来与上面的原始代码块相同,但是客户端代码必须跳过几个环节才能将数据放入本地范围。这假设数组位于名为“some_data.php”的文件中;

global $some_data; //must be the same name as the variable in the data file...
include 'some_data.php';

这会将 $some_data 数组带入作用域,尽管这对于客户端代码来说有点麻烦(我的意见)。

方法#3:通过引用吸气

此方法与方法 #1 几乎相同,但是 getter 函数不返回值而是设置对数据的引用。

<?php
function getSomeDataByRef($some_data)
{
    $some_data = array(
        ...lots and lots of stuff here...
    );
    return $some_data;
}
?>

然后,客户端代码通过声明一个局部变量(称为任意变量)并通过引用将其传递给 getter 来检索数据:

$some_data_anyname = array();
getSomeDataByRef(&$some_data_anyname);

结果

因此,我运行了一个小脚本,该脚本将这些检索数据的方法中的每一种运行 1000 次,并计算运行时间的平均值(在开始和结束时由 microtime(true) 计算)。以下是我的结果(以毫秒为单位,在 MacBookPro 2GHz、8GB RAM、PHP 版本 5.3.4 上运行):

方法一:

AVG: 0.0031637034416199 MAX: 0.0043289661407471 MIN: 0.0025908946990967

方法#2:

AVG: 0.01434082698822 MAX: 0.018275022506714 MIN: 0.012722969055176

方法#3:

AVG: 0.00335768699646 MAX: 0.0043489933013916 MIN: 0.0029017925262451

看起来很清楚,无论如何从这个数据来看,global+include 方法不如其他两个,这是“微不足道的”差异。

想法? 我完全错过了什么吗? (大概……)

提前致谢!

最佳答案

不确定这是否正是您要找的东西,但它应该有助于解决速度和内存问题。您可以使用固定的 spl 数组:

$startMemory = memory_get_usage();
$array = new SplFixedArray(100000);
for ($i = 0; $i < 100000; ++$i) {
    $array[$i] = $i;
}
echo memory_get_usage() - $startMemory, ' bytes';

在这里阅读更多关于大型 php 数组的信息: http://nikic.github.com/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html

您是否也考虑过将数据存储在缓存/内存中?例如,您可以在第一次执行时将 mysqlite 与内存引擎一起使用,然后从那里访问数据:

$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// .. Use PDO as normal

关于php - 在 PHP 中访问大数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10434913/

相关文章:

c - 编码解码请发现故障

performance - 大量内存使用会减慢不相关的代码

performance - Linux性能可以比较每个线程的性能吗?

php - JavaScript 二维数组转 PHP

php - 从 hasMany 关系中获取所有对象并分页

php - 从 Laravel 下载文件

java - Java 中从字符串到二维字符数组

php - 将两个 Laravel 集合与交替的行组合起来

php - 如何将变量作为 cURL 数组中的 url 参数传递给 CURLOPT_URL

c# - 传递一个类/结构与传递多个参数