【问题标题】:How to serialize and unserialize a large file in PHP? [closed]如何在 PHP 中序列化和反序列化一个大文件? [关闭]
【发布时间】:2017-06-26 15:19:56
【问题描述】:

我有一个巨大的复杂数据结构 (TRIE),需要存储以供以后使用。

所以,我正在使用序列化/反序列化(如果有的话,请提出更好的方法):

$fp = fopen("serialized_trie.txt","w+");
fwrite($fp,serialize($root));
fclose($fp);

$root = unserialize(file_get_contents("serialized_trie.txt"));

trie 本身由 100 万个单词组成。所以这是一个很大的尝试。

我需要以某种方式存储这个 trie。将如此大的尝试写入文件需要大量时间。而 unserialize 中的 file_get_contents 会导致整个文件加载到内存中。

我需要使用二进制文件而不是 txt 文件吗?怎么样?

我还阅读了 3 种存储技术: 连载, json_encode, var_export

在这种情况下我需要使用 json_encode 或 var_export 方法吗?

如何快速存储和检索 trie?

【问题讨论】:

  • 我回答了你的最后一个问题,你没有留下任何反馈或 cmets。
  • @gview 刚刚做了:)
  • Serialize 获取变量并将其转换为中间形式。如果您查看服务器上的文件,您会发现不难理解表格。您可以尝试压缩文件以减小其大小,但在每个请求上执行此操作仍然需要大量时间/成本。我在另一个问题中为您提供了内存缓存的标准方法,但您显然出于某种未知原因拒绝了这些方法。有时,现实要求您必须增加复杂性才能实现性能目标。

标签: php file caching trie


【解决方案1】:

您没有指定实际文件大小。话虽如此,serialize 函数基本上将变量转换为可以安全写入磁盘的中间文本形式,但它根本没有优化。

您可以尝试在文件写入之前对其进行压缩:

$fp = fopen("serialized_trie.gzd","w+");
//gzdeflate supports 0-9 levels of compression
//You might want to experiment
fwrite($fp, gzdeflate(serialize($root), 5));
fclose($fp);

阅读:

$root = unserialize(gzinflate(file_get_contents("serialized_trie.gzd")));

扩展名并不重要,因为原始 deflate 文件没有标准,但我建议使用 .txt 以外的其他内容来表明这不是实际的文本文件。

关于内存使用,这在很大程度上取决于你的 trie 结构的大小,你已经指出它很大,但没有任何细节。

作为per my answer to your other question,这将比从内存缓存中读取变量慢很多倍。

Serialize 用于序列化一个或多个 php 变量并从磁盘重新读取这些变量。它用于 php 会话支持。

json

如果您需要返回数据以在需要或支持 javascript 兼容变量的客户端中使用,

json_encode 很有用。

var_export

var_export 在复杂数据结构方面存在一些问题。话虽如此,可以使用 var_export 将 trie 结构写为 php 脚本,然后可以是 require_once()。这可能比这些其他选项更高效。

$fp = fopen("trie.php","w+");
fwrite($fp, '<?php $root = ' . var_export($root) . '; ?>');
fclose($fp);

回读:

require_once('trie.php');

很明显,您的脚本需要将 trie.php 放在 webroot 下可读/可写的位置,但这是另一回事。与其他任何 include() 一样,您需要脚本的路径。

【讨论】:

  • trie 如果写入文件,将超​​过 200MB
  • 查看我的扩展回复。
  • 不言而喻,trie 的写入应该只偶尔进行一次,并且存储的版本在更新之间会使用多次。
  • 谢谢!特里的写作将只有一次。如果我使用 var_export,你能告诉我如何读取文件吗?我需要使用 include 方法吗?
  • 更新了答案。我推荐 require_once,因为如果找不到或无法读取脚本,它会生成运行时错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 2012-09-22
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 1970-01-01
相关资源
最近更新 更多