PHP-*快速*序列化/非序列化?

PHP-*快速*序列化/非序列化?,php,serialization,Php,Serialization,我有一个PHP脚本,它构建了一个超过5MB+的数据库。这很好,但是读取/解析/索引文件大约需要3秒钟 现在我想我可以使用serialize()和unserialize()来加快这个过程。如果CSV文件在此期间没有更改,则没有必要再次对其进行解析 令我恐惧的是,我发现在我的索引对象上调用serialize()需要5秒,并生成一个巨大的(19MB)文本文件,而unserialize()需要27秒才能读回。改进看起来有点不同。;-) 那么,是否有一种更快的机制可以在PHP中从磁盘存储/恢复大型对象图

我有一个PHP脚本,它构建了一个超过5MB+的数据库。这很好,但是读取/解析/索引文件大约需要3秒钟

现在我想我可以使用
serialize()
unserialize()
来加快这个过程。如果CSV文件在此期间没有更改,则没有必要再次对其进行解析

令我恐惧的是,我发现在我的索引对象上调用
serialize()
需要5秒,并生成一个巨大的(19MB)文本文件,而
unserialize()
需要27秒才能读回。改进看起来有点不同。;-)

那么,是否有一种更快的机制可以在PHP中从磁盘存储/恢复大型对象图


(澄清一下:我正在寻找一种比前面提到的3秒时间要短得多的方法来完成反序列化工作。)

如果您想要速度,请以低于最佳的速度写入或读取文件系统

在大多数情况下,数据库服务器能够比读取/写入文件的PHP脚本更高效地存储和检索数据

另一种可能是这样的

对象序列化不以其性能著称,但以其易用性著称,而且它绝对不适合处理大量数据。

我在这里看到两个选项

字符串序列化,最简单的形式如下

  write => implode("\x01", (array) $node);
  read  => explode() + $node->payload = $a[0]; $node->value = $a[1] etc
使用pack()进行二进制序列化


对这两个选项进行基准测试并比较结果将是很有趣的

看来你的问题的答案是否定的

即使您发现了一个“二进制序列化格式”选项,也很可能会降低您所设想的速度

因此,您可能需要考虑使用(正如其他人所提到的)数据库、memcached或在线web服务

我还想补充以下想法:

  • 请求/响应的缓存
  • 您的PHP脚本不会关闭,而是成为一个网络服务器来回答查询
  • 或者,我敢说,更改您当前使用的数据结构和查询方法
    • 应该快得多,因为PHP根本不需要处理字符串:

      // export the process CSV to export.php
      $php_array = read_parse_and_index_csv($csv); // takes 3 seconds
      $export = var_export($php_array, true);
      file_put_contents('export.php', '<?php $php_array = ' . $export . '; ?>');
      

      根据您的web服务器设置,您可能必须先导出.php以使其可执行。

      SQLite随php提供,您可以将其用作数据库。否则,您可以尝试使用会话,然后不必序列化任何内容,只需保存原始PHP对象

      使用JSON之类的格式来存储/加载数据怎么样?我不知道JSON解析器在PHP中的速度有多快,但在大多数语言中它通常是一种快速操作,并且是一种轻量级格式


      首先,您必须改变程序的工作方式。将CSV文件划分为更小的块。我想这是一个IP数据存储

      将所有IP地址转换为整数或长

      因此,如果出现查询,您可以知道要查看哪个部分。
      试试igbinary…为我创造了奇迹:



      为什么不将文件中的信息存储到数据库中?因为脚本是一个工具的一部分,它特别不希望使用数据库依赖项。索引对象是什么样子的?如果您完全可以访问web服务,那么可以选择编写专门用于更快IP2country搜索的PHP扩展模块。另外,监视CSV文件修改日期并通过命名管道提供数据的服务也可以满足您的需要。@stereofrog:它是一个嵌套节点对象树,每个节点对象都有一个
      $value
      (float)、
      $payload
      (string)和
      $left
      $right
      节点引用。没有什么特别的,但是它包含了超过100000个这样的对象。PHP没有二进制序列化格式,可以将内存字节写入磁盘,然后简单地重新读取它们吗?如果CSV都是字符串,并且索引对象实际上包含的信息比文本文件少,为什么它的序列化形式必须如此臃肿?@Tomalak:check-out-pack/unpack@Robert:看起来pack仅适用于单个值,不适用于复杂对象。@tomalak:serialize速度较慢,因为它做了很多在对象和类方面您并不总是看到的事情。它还严重依赖递归来构建嵌套数据结构的字符串表示,这可能也很慢。我认为,当您已经有了面向表的数据(csv)时,关系数据库是最好的选择。树有一个根节点。我的意思是,它能打包整个图形吗?那么恐怕这不是一个选项-\@Tomalak我想请您帮助解决一个与堆栈溢出无关的问题,关于通过引用将字节数组传递给COM对象方法。在这里,当我在互联网上仔细研究时,我遇到了一些相关的问题,这些问题都是由那些陷入同样困境的人发布的。如果你不介意的话,我希望你的专业知识能告诉我怎么做。我将非常感谢您的帮助。您有丰富的数据源,提供了许多创造性的想法,我相信您会想出一些非常流畅的方法。我可以在PHP会话之间共享对象吗?您不能在不同会话之间共享它。尽管通过设置自定义会话ID,您可能会让每个人都使用相同的会话。否则,您必须考虑使用共享内存。如果有人无意中发现了它,请快速记下——不要使用会话存储大型对象,甚至更重要的是——不要让人们共享同一个会话。这首先破坏了使用会话的目的——而且,由于一次只有一个用户可以访问一个会话id,因此它将有效地将请求处理限制为只有一个!会话必须从磁盘/数据库加载@SteveB承认,上下文是模糊的,但我以前在多个应用程序的共享/固定会话中使用过大型数据集。如果您正在构建典型应用程序,典型解决方案通常是好的。@hiburn8我可以
      // export the process CSV to export.php
      $php_array = read_parse_and_index_csv($csv); // takes 3 seconds
      $export = var_export($php_array, true);
      file_put_contents('export.php', '<?php $php_array = ' . $export . '; ?>');
      
      include 'export.php';