【问题标题】:PHP array include performancePHP数组包括性能
【发布时间】:2011-02-15 06:08:08
【问题描述】:

如果我包含一个巨大的 PHP 数组,我会期望什么类型的性能损失? 例如,假设我在“data.php”中有一个 1GB 的 PHP 数组,看起来像

$data = 数组( //1GB 的数据 )

如果我在“header.php”中包含那个巨大的“data.php”文件,它将如何影响“header.php”执行时的性能? 谢谢!

【问题讨论】:

  • 你到底想做什么?你的想法不是实现它的方法。
  • 我正在考虑用不同的方法在我的代码中缓存部分数据库,因为我无法访问 memcache 或 memcached 之类的东西。
  • 您需要使用 MySQL 查询缓存来优化和/或缓存您的查询。 PHP 不是状态持久的,所以你不能缓存在 PHP 的内存中——这就是数据库的用途。见:dev.mysql.com/doc/refman/5.1/en/query-cache.html
  • 1GB 的磁盘数据一旦被 PHP 加载,将占用远远超过 1GB 的内存。除了存储实际数据所需的空间之外,还有与您创建的每个变量和数组元素相关联的各种元数据。你很可能会发现你的 1GB 信息变成了 4GB 甚至 40GB 的实际内存使用量。
  • 感谢 banzaimonkey 的提示。不幸的是,我在共享主机上,无法设置查询缓存。

标签: php performance arrays include


【解决方案1】:

首先,您需要将页面的最大内存增加到超过 1 GB,因为该数组将在每个页面上加载到内存中。这意味着每个脚本都需要读取和解析 1GB 的数据。最好的情况?这为每个页面加载增加了 10 多秒。更有可能的是,页面根本不会加载。

将其存储在数据库中并根据需要进行查询。我无法想象在每个(或事实上,任何)页面上都需要该数组的整个数组(或其重要部分)的场景。

【讨论】:

    【解决方案2】:

    嗯……很多?

    data.php 会很大,因此由于磁盘 I/O 的原因,读取文件需要相当长的时间。然后它必须保留在内存中,因此即使您没有内存限制,它也会影响性能。

    另一个需要考虑的瓶颈是max_execution_time 限制。如果您需要在内存中存储 1GB 的数据,您很可能做错了什么……您是否考虑过存储原始(填充)数据,每行一个元素,然后只请求该文件的一些特定字节?


    示例(写):

    $values = array
    (
        0 => '127.0.0.1', // 9 chars
        1 => '127.0.0.2', // 9 chars
        2 => '...', // 3 chars
        3 => '255.255.255.255', // 15 chars - this is the max in our set
    );
    
    foreach ($values as $key => $value)
    {
        // lets pad each value to 15 bytes
        $values[$key] = str_pad($value, 15, ' ', STR_PAD_LEFT);
    }
    
    file_put_contents('./test.data', implode('', $values), LOCK_EX);
    

    示例(阅读):

    echo ltrim(file_get_contents('./test.data', false, null, 0 * 15, 15)); // 127.0.0.1
    echo '<hr />';
    echo ltrim(file_get_contents('./test.data', false, null, 1 * 15, 15)); // 127.0.0.2
    echo '<hr />';
    echo ltrim(file_get_contents('./test.data', false, null, 2 * 15, 15)); // ...
    echo '<hr />';
    echo ltrim(file_get_contents('./test.data', false, null, 3 * 15, 15)); // 255.255.255.255
    

    【讨论】:

    • @tau:我在回答中提供了一个示例,请查看。
    【解决方案3】:

    只是在黑暗中拍摄,但看到你不能使用 memcached 等,你是否考虑过使用基于磁盘的缓存,或者编写你自己的类。因此,在您使用 memcached->storeValue (或任何调用)的地方,您将改为调用您自己的函数,该函数会将数据写入文件。这个问题的复杂性可能超出了这个问题的范围。另一种选择是使用已经编写好的东西,例如 Zend Framework 及其各种缓存类,它们应该允许您使用基于磁盘的缓存。其他框架可能有自己的可以写入磁盘的缓存系统(codeIgniter、CakePHP 等)。 第三种选择是将生成的数据缓存到 mysql 数据库中,虽然这可能看起来有点疯狂,但如果做得正确,它仍然会以与任何其他缓存大致相同的方式为您提供速度提升。 在缓存时,值得花一些时间进行基准测试,以确保您确实通过这样做来消除瓶颈。

    【讨论】:

      【解决方案4】:

      取决于您的服务器、CPU、内存、网络服务器、硬盘等。

      但很可能:这不是一个好主意。使用fread 或其他方式读取文件会更好。

      【讨论】:

        【解决方案5】:

        如果你在data.php上存储了1G的数据,那么解析1GB的文件然后将数组的数据放到内存中需要很长时间,需要时间和空间。一台服务器一次处理多个请求,即 1GB 乘以 100 到 1000 的总内存,具体取决于您网站的每日视图。

        为什么不尝试将其拆分为多个文件或使用数据库?甚至,创建一个后台服务,用 C 语言硬编码 1GB 数据,然后 PHP 调用该服务来提取部分数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-21
          • 2011-08-11
          • 2017-01-07
          • 2010-10-21
          • 2013-06-03
          • 2017-03-02
          • 1970-01-01
          相关资源
          最近更新 更多