代码之家  ›  专栏  ›  技术社区  ›  jW.

在PHP中缓存对象而不使用序列化

  •  10
  • jW.  · 技术社区  · 16 年前

    我有一个在PHP脚本中创建的复杂对象。我正在寻找一种存储此对象的方法,以便后续请求不必重新创建它,也不必花费时间取消序列化和重建它。使用xdebug,我发现我花费了整个请求时间的一半来构建这个对象。即使我将对象显式存储在APC(或memcache)中,取消序列化并加载所有类所需的时间几乎与首先创建对象所需的时间一样长。

    我不确定这是否可行,但我想我应该问问社区。

    9 回复  |  直到 16 年前
        1
  •  9
  •   William OConnor - csevb10    16 年前

    据我所知,如果不序列化,就不可能在PHP中缓存对象。但是,一般来说,缓存机制(APC、Memcache等)实际上是在尝试删除数据库连接,而不是提高性能(从而降低总体数据库压力)。这是 肯定 memcache等如何在Drupal中使用。换句话说,缓存机制应该允许您进行扩展,尽管它们可能不会特别提高性能。
    实现缓存机制应该允许您更轻松地向外扩展,即使对于单个连接,每台机器的性能没有比以前更好。在某个阈值下,DB性能将急剧下降,缓存机制将有助于缓解这一问题。

        2
  •  6
  •   codeincarnate    16 年前

    调查 Igbinary PHP扩展。它是序列化和非序列化的替代品,可能适合您的需要。

    它以二进制格式存储对象,而不是字符串,这减少了内存使用,也减少了序列化和取消序列化对象的时间。

    尽管这需要经过对象的非序列化过程,但二进制格式可能会提高性能,使此过程在应用程序中使用更为合理。

        3
  •  3
  •   Sean McSomething    16 年前

    也许解决办法是不要建造一个单一的、巨大的、昂贵的物体。

    考虑到PHP应用程序在每次加载页面时几乎都是从一张白纸开始的,因此依赖于单个巨型对象的解决方案不适合这种语言。因为你没有详细说明你的目标是什么&它的作用是什么,我不能确定,但我怀疑您并不真的需要该对象在每次页面加载时所做的一切。如果是这样的话,你可能会认真考虑把它分解成一些更小、更简单的类,你可以根据需要实例化。

        4
  •  2
  •   Nicolas    16 年前
        5
  •  1
  •   Pascal MARTIN    16 年前

    不,不可能以非序列化形式存储PHP对象;至少,使用以下缓存解决方案是不行的 (我试过这些;不知道可能存在的另一个) :

    • 文件夹
    • memcached
    • 空气污染指数
    • 数据库 (是的,您可以考虑在DB中缓存东西^^^例如,Drupal默认这样做)

    大的 ? 你有没有办法缩小它的尺寸?

    例如,你在这个对象中有一大堆HTML代码吗?如果是,它是否可以存储在另一个缓存条目中?
    (序列化是“将某些数据转换为字符串;因此,如果您已经在使用字符串,则无需重新序列化以将其存储在缓存中)

    或者,从头开始创建它不需要太多时间?在这种情况下,缓存真的有必要吗?

        6
  •  1
  •   darkpeguin darkpeguin    16 年前

    如果可能的话,在您的平台上编写一个简单的守护进程,在启动时加载您的树,然后通过套接字应答请求。您的服务器进程可以分叉并回答查询,而无需重新创建树。 编写守护进程不是一件小事,但有很好的文档记录(至少对于C)。使用pcntl和posix扩展将其转换为PHP应该没有问题。

        7
  •  1
  •   JSON    10 年前

    虽然PHP可以为各种数据类型提供许多动态特性,但这些操作并不神奇,数据仍然作为基本的本机数据类型存储在zval中,从技术上讲,zval是本机zend api中的一个复杂哈希表。与任何语言中的任何其他数据类型一样,每个zval将只存在有限的一段时间。对于PHP,这段时间是(最多)处理HTTP请求的时间。在任何情况下,要使此数据比单个请求持续时间更长,必须将其从原始zval转换为其他形式的,然后以某种方式存储(这包括复杂类型,如PHP对象以及基本类型,如INT)。这总是需要重新初始化每个zval,然后将存储表单中的数据转换回zval中的各种PHP数据类型。某些存储格式(如BSON)将比PHP序列化字符串快,但(至少到目前为止)这不会带来太多明显的性能提升,因为它远没有达到跨多个请求维护原始zval的性能。您仍然需要以某种方式序列化这些数据,经历存储数据、获取数据和取消序列化的过程。目前还没有真正的解决办法。

        8
  •  0
  •   stefs    16 年前

    在这种情况下,更好的选择是编写自己的服务器。

    这在php中很容易实现——您已经有了代码——但在编写服务器时,php可能不是大多数人的首选。

    • 并非所有主机都允许自定义cli脚本
    • 如果您的决策树发生更改,您必须通知服务器重新生成该树
        9
  •  0
  •   Bobík Russia Must Remove Putin    10 年前

    您可以将应用程序重写为 ReactPHP 是什么在一个长期运行的PHP进程(就像Node.js或Web.py)中创建了Web服务器。然后,您可以一次性(在服务器启动时)将大对象构建为全局变量,并从请求事件处理程序访问它。