Hardcoded

free(DOM);

Static call versus Singleton call in PHP

with 40 comments

Introduction

In the past several months I’ve been working with a rather large application built with symfony. I noticed that symfony makes heavy use of the Singleton pattern (other frameworks, like Zend do that too); everywhere in the code there were pieces like this one:

<?php
// ...
sfSomething::getInstance();
// ...
?>

I know that in more than half of the situations, you can write your code using plain static classes, with some initialize() method, as an alternative to writing singletons. For example, this is a dummy Singleton:

<?php
class DummySingleton {
    private function __construct(){}
    private function __clone(){}
    public static function getInstance(){
        if(self::$__instance == NULL) self::$__instance = new DummySingleton;
        return self::$__instance;
    }
    public function foo(){
        echo 'I am DummySingleton::foo()';
    }
}
?>

Now this is a completely useless class, but it suits our purpose of illustrating the Singleton. Notice the amount of code needed by the Singleton pattern. Except the foo() method, all the code in the class makes sure you have only one instance at any time during the execution.

Now let’s write a static class that does the same thing as the Singleton:

<?php
class DummyStatic {
    static public function foo(){
        echo 'I am DummyStatic::foo()';
    }
}
?>

This is much cleaner, as we don’t need the extra code the Singleton needs, and can focus on our task at hand.

Performance comparison

Let’s compare the performance of the two approaches. I’ve written a small test script that looks like this:

<?php

/**
* A singleton class
*/
class TestSingleton {
    // singleton code
    private static $__instance = NULL;
    private function __construct(){}
    private function __clone(){}
    static public function getInstance(){
        if(self::$__instance == NULL) self::$__instance = new TestSingleton;
        return self::$__instance;
    }

    // our actual code
    public $val = 0;
    public function test(){
        for($i=0;$i<30;$i++) $this->val += $i;
    }
}

/**
* a plain static class (all members are static)
*/
class TestStatic {
    static public $val = 0;
    static public function test(){
        for($i=0;$i<30;$i++) self::$val += $i;
    }
}

// how many runs
$runs = 500000;

// benchmarking Singleton
$start = microtime(TRUE);
for($i=0;$i<$runs;$i++) TestSingleton::getInstance()->test();
$run1 = microtime(TRUE) - $start;

// benchmarking static
$start = microtime(TRUE);
for($i=0;$i<$runs;$i++) TestStatic::test();
$run2 = microtime(TRUE) - $start;

echo '<pre>';
echo 'test singleton: '.number_format($run1, 8)." s\n";
echo 'test static:    '.number_format($run2, 8).' s';
?>

Basicly, I put together the two types of classes. Both have a method called test(), which does some arithmetic operations, just to have something that spends some execution time.

I’ve ran this script for various values for the $runs variable: 100, 1k 10k, 100k, 200k, 300k, 500k and 1M.

Test results

Number of runs Singleton call time (s) Static call time (s)
100 0.004005 0.001511
1,000 0.018872 0.014552
10,000 0.174744 0.141820
100,000 1.643465 1.431564
200,000 3.277334 2.812432
300,000 5.079388 4.419048
500,000 8.086555 6.841494
1,000,000 16.189018 13.696728

I have also done some spreadsheet magic, and generated this chart:

As you can see, for a relatively small number of runs (<1k), the Static code is significantly faster than the Singleton, an than it stabilizes arround 15% faster than Singleton, as I expected. This is because every function/method call involves some operations (symbol lookup, stack manipulation etc.), and each call to the Singleton method, in fact, also calls the getInstance() static method.

Conclusion

It may not be that obvious that making extensive use of Singletons has this kind of side effect; however, if your code has more that 100 or 1,000 calls to some getInstance() method of a Singleton class, you might want to consider caching the reference to the object it returns, or even refactoring the code to use only static method calls.

You might say that you need an object because you do stuff in the constructor. That can be easily achieved with some kind of static initialize() method, that should be called once in your code, just before usage. If you have some auto loading mechanism in place, you could call it just after loading the class, for example, if you want to automate the initialization process. But keep in mind that this is not a 100% replacement for Singletons; you need an object if you want to serialize/unserialize it (for caching, some RPC call, etc.).

Update.

Tested with Facebook’s HPHP compiler:

I’ve tested the script using the HPHP compiler, and the results are spectacular. While keeping the same time ratio between the Singleton and Static calls, what stroke me is the huge difference (HPHP is ~ 200 times faster):

Number of calls Time spent (Apache) Time spent (HPHP)
Apache Singleton call Apache Static call HPHP Singleton call HPHP Static call
100 0.004005 0.001511 0.00001502 0.00000906
1,000 0.018872 0.014552 0.00008988 0.00007486
10,000 0.174744 0.141820 0.00075102 0.00063801
100,000 1.643465 1.431564 0.00829983 0.00795388
200,000 3.277334 2.812432 0.01839614 0.01339102
300,000 5.079388 4.419048 0.02502608 0.01932502
500,000 8.086555 6.841494 0.04114008 0.03280401
1,000,000 16.189018 13.696728 0.07872796 0.06373119

Happy coding.

About these ads

Written by Doru Moisa

March 2, 2010 at 1:39 am

Posted in Development, php

Tagged with , , , ,

40 Responses

Subscribe to comments with RSS.

  1. [...] Moisa has written up a new post with some benchmarks comparing static calls versus singleton calls for a few different situations. n the past several months I’ve been working with a rather [...]

  2. [...] Moisa has written up a new post with some benchmarks comparing static calls versus singleton calls for a few different situations. n the past several months I’ve been working with a rather [...]

  3. Social comments and analytics for this post…

    This post was mentioned on Identica by moisadoru: Singleton vs. Static calls in PHP http://wp.me/pep2n-1r #php #benchmark…

  4. [...] here to see the original: Static call versus Singleton call in PHP « Hardcoded [...]

  5. Don’t forget: static methods and singletons are hard to test. I like to avoid them where possible nowadays. Given how much performance you can gain from something like hphp it makes sense to try and make your code testable and easy to understand.

    Rory

    March 2, 2010 at 8:53 am

  6. Why would you get the singleton instance on every loop?

    penfold

    March 2, 2010 at 10:32 am

    • In this test case you can easily cache the object returned by getInstance() and re-use it. But when you handle a rather large codebase, you get hundreds, even thousands of getInstance() calls spread through the whole application (do a grep on a large symfony app, and you’ll see what I mean).

      Doru Moisa

      March 2, 2010 at 10:37 am

  7. Agreed on the testability, though there are a few strategies to get around this. See http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html for an upcoming solution on mocking/stubbing static methods. The only problem is it requires PHP 5.3 for late static binding and PHPUnit 3.5, which is not released yet.

    Also check out http://sebastian-bergmann.de/archives/882-Testing-Code-That-Uses-Singletons.html. Interestingly enough, in the comments you’ll see Matthew Weier O’Phinney (Zend Project Lead) declare a ban on singletons in ZF 2.0.

    Ryan Horn

    March 2, 2010 at 10:43 am

    • Good to know that people are learning from their mistakes :). Hopefully we’ll have new and better versions of the frameworks we use day by day.

      Doru Moisa

      March 2, 2010 at 10:58 am

  8. Just like comparing Black Plague and Spanish Flu… :)

    Giorgio Sironi

    March 2, 2010 at 12:04 pm

    • Haha!! I like your humour!

      Steve

      March 17, 2012 at 5:29 am

  9. The point of a Singleton is to only return a single instance of a class, such as a db class. Your comparison with a simple static method makes no sense?

    James

    March 2, 2010 at 12:11 pm

    • I agree with this. All the example really tells me is there is a price to be paid when using a Singleton, so it better be the right tool for the job.

      It would be interesting, for both performance and code complexity, to see this comparison done on a meaningful Singleton object and its static counterpart.

      Mike

      March 2, 2010 at 6:31 pm

  10. [...] Static call versus Singleton call in PHP Hardcoded [...]

    Anonymous

    March 2, 2010 at 1:29 pm

  11. If you’re fetching an instance of any class 100 or more times during a request, you’re doing something wrong. The performance cost of a Singleton is the least of your worries.

    Steve High

    March 2, 2010 at 2:46 pm

  12. I’ve modified your code a bit and you can check it here:
    http://php.pastebin.com/E3BQndcA the purpose beeing to measure more durations (taken at different processor loads) and compute an average.

    What I’ve found is that Singleton vs Static resulted in a 9.89% to 13.76% increase of duration. Only making a single run with the Singleton vs Static, resulted in a 198.66% increase, but for that single run, the actual time was 24.12 microseconds, which is fairly negligible.

    I did not test with HPHP, and I ran two cycles of 10 repetitions with all the ‘runs’ values that you originally tested (check my code for a better understanding) and I stored the results in the session.

    What you can extract from this little experiment is that even if Singletons are 10% slower than the Static calls, that doesn’t mean it is the best way of doing things.

    Personally I try to avoid creating classes that only have static methods in them as I find them hard to maintain.

    It’s just like writing a bunch of functions with no application logic whatsoever and calling it OOP !

    Mihai Bojin

    March 2, 2010 at 3:47 pm

    • A nice experiment I did after the first test was to cache the object instance returned by the Singleton’s getInstance() method call. This resulted in a huge speed increase, but I decided ti dismiss this, because in a typical large application (zend, symfony, magento etc.), you will get hundreds of getInstance() calls per request, and I wanted this to be closer to the real situation than any other optimized/ideal test cases.
      Every performance test should be created to resemble as close as possible the real world situation, so you can draw some correct conclusions, and optimize where the bottleneck is.

      Doru Moisa

      March 2, 2010 at 4:09 pm

  13. [...] This post was Twitted by memphys [...]

    Twitted by memphys

    March 2, 2010 at 7:09 pm

  14. [...] Originally posted here: Static call versus Singleton call in PHP « Hardcoded [...]

  15. [...] Continue reading here: Static call versus Singleton call in PHP « Hardcoded [...]

  16. It is worth noting that “design patterns” aren’t meant to make code execution more efficient, but for development’s sake.

    As it has been suggested, a singleton is not meant to be the same as a static method or a single function. It is meant to limit instantiation to a single object, most likely a resource of some kind.

    In my opinion, both static methods and classic singletons lack in comparison to dependency injection. There are a few frameworks for PHP out there, but simple IOC library can be implemented in a few dozen lines of code.

    I realize your post is not about best coding practices, but about performance trade-offs. My experience says it isn’t worth the speedup.

    Joey

    March 3, 2010 at 2:01 am

  17. What’s the exact PHP version and platform you were testing on? Performance testing is fraught with hidden pitfalls. There could be hidden variables that impact the outcomes, although the HPHP comparison provides more confidence in your result, methinks.

    Yuriy

    March 3, 2010 at 9:48 pm

    • I’ve done the tests on my HP Compaq 6820s with a Core2 Duo T7500 2.2Ghz, 4GB RAM, with Ubuntu Lucid 10.04 (kernel 2.6.32-10-generic and 2.6.32-14-generic) x86_64,
      Apache 2.2.12 and 2.2.14, PHP 5.2.10 w/ Suhosin and 5.2.12 w/ Suhosin.

      Also, I’ve tested it on my home router/server, an old Athlon 1800 Mhz, 256 MB RAM (FreeBSD 8.0, Lighttpd 1.4.23 and PHP 5.2.8 w/ Suhosin),

      On the FreeBSD system the difference was a little smaller, about 6% for 100 … 1k calls, but then it stabilized around 4%.

      Doru

      Doru Moisa

      March 4, 2010 at 11:09 am

  18. [...] post by Doru Moisa, Static call versus Singleton call in PHP, compares the performance of a singleton class with that of a static method. This is relevant, of [...]

  19. I think the test is a bit rigged in favor of the static example… how about:

    // benchmarking Singleton
    $instance = TestSingleton::getInstance();
    $start = microtime(TRUE);
    for($i=0;$itest();
    $run1 = microtime(TRUE) – $start;

    Of course two function calls is slower is slower than one… In a real scenario you don’t need to get the instance all the time. If you care about performance you vcan store it and eliminate half the calls.

    By the way singleton exists with a reason. It has the possibility for future developments to move away from the “only one instance” part. A quick example: if you use singleton for an object to store user identification/privileges, then a future version could include bubble-like subsessions, when you change to a different user (something like UserManager::setInstance) then do some tasks and switch back to the current user.

    If you use static methods for the functionality the above example is impossible without hevy refactorization.

    The question was good, but development possibilities usually outweigh a bit of performance loss (that’s why we don’t use CGI-s written in ASM ;).

    vbence

    March 7, 2010 at 10:37 am

    • You are trying to optimize the test, which defeats its purpose. When you have a very large application with hundreds maybe thousands of files (think of social network applications), you will have hundreds maybe thousands of getInstance() calls, which is exactly what my test does. And I was not trying to sack the Singleton, of course there are justified uses of this pattern; I was just comparing it to the static approach (didn’t find a comparison of these two on the web, so I did one) and observe the difference between them.
      Who knows, maybe it helps someone ;)

      Cheers,
      Doru

      Doru Moisa

      March 8, 2010 at 8:19 am

  20. [...] blog post by Doru Moisa about Static call vs. Singleton… very [...]

  21. Also interesting:

    “test singleton” is slower than “test static” is slower than “not using OOP”!

    Try it – I enhanced your example-code like this:

    (…)

    function TestNonOOP(){
    $val=0;
    for($i=0;$i<30;$i++) $val += $i;
    }

    (…)

    // benchmarking non OOP
    $start = microtime(TRUE);
    for($i=0;$i<$runs;$i++) TestNonOOP();
    $run3 = microtime(TRUE) – $start;

    (…)

    echo 'test non OOP: '.number_format($run3, 8).' s';

    And the result I got on my machine:

    test singleton: 10.26051688 s
    test static: 7.92998219 s
    test non OOP: 4.04378700 s (!!!)

    So why use "static functions" or even classes when using OOP performes so bad!?!

    Simon Schmitt

    April 13, 2010 at 12:16 pm

    • Great Job!

      Ceson

      April 19, 2010 at 4:18 pm

    • It Depends on what you need … When we try to create larger application, it’s debatable between OOP vs not OOP; between easiness to expanding or the performances of our application …

      duno

      April 20, 2011 at 8:10 am

  22. [...] Singleton pattern is not the same thing as a static context. Doru Moisa made a comparison about the performance of Static call versus Singleton call in PHP, you might to check it out. Based on his observation, it’s observed that Static calls are [...]

  23. Interesting article, I’ve been grappling with the static call vs singleton question for a bit myself.

    Too many static calls feel like procedural code, but interesting to see they are potentially faster. One commenter observed that the singleton is where you just need once instance of a class, and referenced databases. I’d love to see some more discussion on this, as I’m wondering why I can’t just wrap up my database connection and functions in static methods. Do we even need an object?

    Great post and great debate.

    Ollie Phillips

    October 29, 2010 at 9:33 am

  24. [...] Static vs Singleton en PHP: Personalmente me parece una decisión incorrecta la de usar static en lugar de singletons “porque es más rápido”, hay situaciones donde por la naturaleza de no compilación de PHP pueden dar problemas, pero preferir una estructura más sucia sólo por velocidad… Pero bueno, ahi queda el artículo. [...]

  25. Actually the singleton is faster, just optimize the code by putting getInstance out of the for loop ! :d

    michal przybylowicz

    February 14, 2012 at 4:30 pm

  26. The argument that you can replace all Singleton classes with statics does not hold water where initialization state is required. To be fair, this is mentioned in the original post but not clearly. With the static approach you would have to make a call to check for initialization of the class for each and every static call. This will make the static version much slower. With the singleton approach you would check in the getInstance call. As the programmer should cache the getInstance result the initialization check call would only happen once per client on, say, a website.

    Let’s do a quick bit of maths.

    If a website is visited by 5000 clients and a class is used that requires initialization, and then ten method calls are made to that class then the results are:

    Singleton:
    Initialization Check Calls: 1 x 5000 = 5000
    Initialization Calls: 1 x 5000 = 5000
    Method Calls: 10 x 5000 = 50000
    Total : 60000 calls.

    Static Class
    Initialization Check Calls: 10 x 5000 = 50000
    Initialization Calls: 1 x 5000 = 5000
    Method Calls: 10 x 5000 = 50000
    Total: 105000 calls

    So for a static class where the class must have an initialization state to operate then Static classes have an overhead of 45000 calls. If you are railing against this calculation, just sit calmly and think again – the math is correct.

    This is a key reason (but not the only one) that Singleton exists.

    So, Singletons where the class requires initialization state, Statics where it does not. Pretty easy design choice really.

    However, lets look more closely. For websites driven by PHP, do you even need the singleton pattern at all.
    If you use a global instance of a class (oooh globals!) then you avoid the whole getInstance call as you are working just on a single instance. Of course, this requires your developers to be smart and not just ‘accidentally’ instantiate another instance of the class for which you must only have a single instance – we all know how good contractors are at following the rules ;-)

    Singleton protects devs from themselves. The overhead is worth it to prevent hard to find bugs.
    :-D

    Aeomer

    June 27, 2012 at 2:10 pm

    • Agree, but, since PHP does not have static initialization blocks like Java & others, the initialization could be done via a init() method called during the application bootstrap. Nevertheless, both singletons and static classes are delicate subjects.
      A more elegant solution would be to use a dependency injection mechanism which would provide the same instance wherever needed.
      Coming back to singletons, I tend to avoid them, as they are pretty hard to work with in certain conditions (ex. unit testing). See a great analysis on the subject on Misko Hevry’s blog: http://misko.hevery.com/2008/08/25/root-cause-of-singletons/

      Doru Moisa

      June 27, 2012 at 2:26 pm

      • I agree that dependency injection can help with unit testing greatly. In order to replace Singletons with DI you would need to use an auto dependency injection pattern to absolutely ensure the same object instance was injected where required. My problem with this is one of performance, as ADI requires some kind of XML or metadata be parsed. Anyone who has ever looked closely at XML parsing knows it’s horrifically slow (relatively speaking) for even small XML formatted data – it’s the nature of that particular beast. That leaves us with an optimized metadata approach, but there will still be an overhead for parsing.

        This is the point where my argument hits a stumbling block, I have not had time to create benchmark data for such an implementation – it just ‘feels’ like it would be slower than . Has anyone actually tried such an implementation? Does anyone have links to concrete examples?

        On another note: I liked Misko Hevry’s discussion of when to use Singletons. He hit upon the exact and only reason for a Singleton – Global State. Certainly, this is the one and only way-and-why I ever use Singletons. Maybe that is the reason I have never had an issue with them.

        Aeomer

        June 28, 2012 at 10:43 am

  27. I should have added to my comment that when I say ‘Global State’ I mean when having anything other than one of something would be very bad. Hevry sited a Logger as one such acceptable situation, but I don’t think you need Global State for that – it’s not really that acceptable just because it’s harmless. But what about ACLs? You most certainly don’t want to re-parse ACLs frequently. And what about when an ACL is changed? How can we reconcile multiple instances of what is usually a global issue? Change one of your ACL instances and the others may never know what happened. The truth of of programming is there will always be at least one global context – you can’t get away from it, even if it ends up being a piece of hardware like a CPU core or an HDD.
    I once saw some code that wrapped all ‘global’ instances in a single container that acted as the only global. This actually allowed for multiple global contexts (think of it like having multiple documents), which does not break OOP but somehow feels ‘dirty.’ :-)

    Aeomer

    June 28, 2012 at 11:01 am

  28. There are a number of benefits in using the singleton pattern and not many people understand the benefits of it.

    OOP tries to cut down on code duplication *and* maintenance.

    One maintenance nightmare is “hardcoded” class names, like the one mentioned right at the top:

    sfSomething::getInstance()

    Imagine that you have a large project with many hundreds of source code files.

    Imagine that sometime after you/someone wrote the code there is a need to use a class *other* than “sfSomething”.

    What do you do?

    You’ll have to go through all the source code and change references to the class “sfSomething” to “sfSomethingElse”

    It could be a bit of a hassle, couldn’t it?

    *However*, if you used a singleton pattern with a global function all this headache can be avoided, eg:

    function db() {
    static $dbi = false;
    if ( !$dbi ) {
    require_once ‘sfSomethingElse.php’;
    $dbi = new sfSomethingElse( …. );
    }
    return $dbi;
    }

    Now, you only have to replace the class name in one place not in hundreds of places and also, should you decide to replace sfSomethingElse with a different database you can do it in one place as well.

    Even if there was a need to use multiple databases, this “centralised” singleton method could be extended/used to cut down on software maintenance.

    monica

    July 6, 2012 at 3:07 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: