12

I have a complex object that I create in a PHP script. I am looking for a way to store this object such that subsequent requests do not have to recreate it, or spend time unserializing and rebuilding it. Using xdebug I find that I spend half of the entire request time building this object. Even when I store the object explicitly in APC (or memcache), the time to unserialize it and load all of the classes takes almost as long as creating the object in the first place.

I do not know if it is possible to store and later load a "compiled" object in PHP. Is this possible? Are there other solutions?

I am not sure that this is possible, but I thought I should ask the community.

EDIT: The object is a binary tree, and used as a decision tree. The code is basically an API that is required to quickly return an answer from the tree. This all needs to perform at an ever increasing rate so I am trying to maximize the performance wherever possible.

5
  • Not that this is a way to do it 'without' serialize. But might want to look into __sleep() and __wakeup() methods so it can automagically rebuild the class. us3.php.net/manual/en/… Commented Jul 27, 2009 at 21:18
  • 1
    @Chacha Thanks for that info. I am not sure it is a solution, but I definitely learned something new from it! Thanks. Commented Jul 27, 2009 at 21:22
  • 3
    Storing an object, by definition, requires serialization. If you really need repeated, rapid access to a large, in-memory binary tree, a PHP script invoked on every request just isn't the right solution. Commented Jul 28, 2009 at 0:15
  • Can't you store the large object in APC without serializing it? php.net/manual/en/function.apc-store.php#73560 Commented Jan 30, 2013 at 20:06
  • @rcourtana When you store an object in APC an intrinsic serialize is called. If you spin up your profiler and watch perform this store/retrieval from APC you will find that you spend a large amount of time serializing Commented Feb 27, 2013 at 23:06

9 Answers 9

9

As far as I'm aware, it's not possible to cache objects in PHP without serializing. In general, however, caching mechanisms (APC, Memcache, etc) are really trying to remove the db connection(s) more than improve performance (and thereby decrease the overall DB strain). This is definitely how memcache, et al are employed with regards to Drupal. In other words, the caching mechanisms should allow you to scale, though they may not particularly improve performance.
Implementing a caching mechanism should allow you to more easily scale outward, even if the performance per machine is no better than before for a single connection. At a certain threshold, DB performance will degrade sharply, and the caching mechanisms should help alleviate that issue.

Sign up to request clarification or add additional context in comments.

Comments

6

Look into the Igbinary PHP extension. It is a drop in replacement for serialize and unserialize and it may suit your needs.

It stores objects in a binary format instead of a string which decreases memory usage and also decreases the time to serialize and unserialize objects.

Although this does go through the process of unserializing an object, the binary format may increase performance enough to make this process reasonable for use in your application.

1 Comment

From my reading about Igbinary, it doesn't seem that this will necessarily increase performance. I don't see any documentation stating an increase in speed, only a decrease in size of serialized objects.
4

Maybe the solution is to not build a single, massive, expensive object.

Given that a PHP application pretty much starts from a clean slate on every page load, a solution that depends on a single, giant object is a poor fit to the language. Since you don't go into much detail about what your object is & what it does, I can't be certain, but I'd suspect you don't really need everything the object does on every page load. If that's the case, you might seriously consider splitting it into a number of smaller, simpler classes that you can instantiate as needed.

Comments

2

igBinary is a useful extension that may help you achieve a faster serialize/unserialize process. It replaces the standard serialization mechanism with a more clever, binary one. If you manage your own server and can install this, it's worth a try.

Comments

1

NO, it is not possible to store a PHP object in a non-serialized form ; at least, not with the following caching solutions (I've tried these ones ; don't know about the other that might exist) :

  • files
  • memcached
  • APC
  • Database (yeap, you can think about caching things in DB ^^ Drupal does it by default, for instance )

If it takes that much time to unserialize your object, maybe it is really big ? Is there any way you could reduce it's size ?

For instance, meybe you have a big bunch of HTML code in that object ? If so, could it be stored in another cache entry ?
(serialization is "transforming some data to a string ; so, if you are already working with a string, you don't need to re-serialize it to store it in cache)

Or maybe it doesn't take much time to create it from scratch ? In this case, is caching really necessary ?

2 Comments

BTW, Wordpress Does Not By Default Cache anything. So, yes you can cache in the Database.
The object does not store any extra html or information. The question states that it is very expensive to create from scratch, and that is the whole goal of "caching" the object.
1

if possible on your platform write a simple daemon that loads the your tree at startup then answers requests over a socket. Your server process can fork and answer queries without recreating the tree. Writing a daemon is not trivial, but very well documented (at least for C). You should have no trouble translating this to PHP using the pcntl and posix extensions.

Comments

1

While PHP can provide a lot of dynamic features for various data types, these operations arn't magical and the data is still stored as basic native datatypes within whats called a zval which is technically a complex hashtable within the native zend api. Like any other datatype in any language, each zval will only exist for a finite period. For PHP, this period is (at max) the period of handling a HTTP request. Under any situation, to make this data last longer than a single request, it must be converted from the original zval into some other form of and then stored in some way (this includes complex types such as PHP objects as well as basic types such as ints). This will always require re-initializing each zval, and then converting the data back from the stored form back into various PHP datatypes within the zval. Some storage formats such as BSON will be faster than PHP serialized strings, but (at least as of now) this will not provide much of a noticed performance jump as it is nowhere close to the performance of maintaining the original zval across multiple requests. You will still have to serialize this data in some way, go through the time of storing it, then fetching it, and then unserializing it. There are no real solutions for this at this time.

Note that PHP can be said to have three different scopes: the SAPI, which initiates and ultimately handles all state within each request; extensions, that are initiated before each request event is started; and then script scope which is initiated by each request. All PHP vars are initiated within the script scope, but can be accessed by both extensions and the SAPI. But the only scope that can exist beyond each single request is the SAPI. In other words, a PHP object can only be maintained across multiple requests within the SAPI (an extension cannot help with this problem at this time), therefor only a custom SAPI is able to maintain zvals across requests.

Comments

1

You can rewrite your app to ReactPHP what create webserver in one long-running PHP process (just like Node.js or Web.py). Then you can build your big object once (on server start) as a global variable and access it from request event handlers.

Comments

0

in this case a better option would be to write your own server.

it's easily doable in php - and you already have the code - but php may not be the first choice of most when it comes to writing servers.

  • it may become the new bottleneck of your app (as php is not really multithreading-ready and requests are answered serially)
  • not all hosters allow custom cli scripts
  • if your decision tree changes, you have to notify your server to rebuild the tree

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.