SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 26
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How to optimize DI (PicoContainer)?

    I have re-written my cms to work with PicoContainer.
    That thing works like charm, but the problem is the overhead.
    My PageRenderTime went from 0.34s to nearly 2s on my index, which displayes nothing more than: "Hello, Guest!".

    In WinCacheGrind it's first Picos Reflection, then RegComponentImpl at second place, then some db-prepare's, and then requireFiles.

    how to optimize an object-oriented cms using pico for speed?
    Where to start? What to do? Best practices to gain speed?
    Is it possible to further optimize picocontainering or reduce it's overhead?
    Is it good to bundle classes or strip off interfaces or strip out comments, before php is interpreted?

    Thanks for Help - best regards, vain

  2. #2
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > Best practices to gain speed?

    Don't do a refactoring until you have cause to do so

    If the temptation was there to use Pico then fair enough; Doing development for research purposes with a third party library is all good, but to reiterate what I have posted in my first sentence, did you have cause for the refactoring?

    Or did you do it for the sake of doing it; What I would have done, was to render the use of Pico on something that was sandboxed, then take it from there, but certainly not on a live application without having previous experience with the said third party library.

    Hindsight is a good thing I suppose

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, you are right! Hindsight! I read about that di-library and wanted to see it's "magic" in an application, which is not clutterd with "global $this, $that". Well - ok i got what i wanted, but price is a little high.

    On the other hand: That refactoring was badly needed and cleaned things up. With my last tries i got it to 1,2secondes with APC. Not too bad.
    After all, i guess, i can call it an experimental fork.

    That leads me to another question:Are these DI-libraries just theoretical stuff, which are never used? Or is there an Live Application out there, which uses Phemto or Pico? I have found out that enterprisegroupwaresystem is using phemto, but thats it. Looking at TypoScript or Joomla, well they abuse globals all over their code.

  4. #4
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I haven't been programming in v5 for very long so I don't have a lot of experience with DI containers. What I've found so far is that they are just perfect if you want to make some kind of behaviour easily configurable. You can supply a few standard options (ie classes) and if need be users can add others of their own. For example, in Rephactor, there are a couple of injectable policies (using Phemto) which allow some control over the precise behaviour of a refactoring operation.

    I'd always have some kind of assembly layer but if nothing needs to be opened up to make it easily configurable, I'll just wire everything together with a hard-coded factory.

  5. #5
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have not used Dependency Injection in any of my applications because I've never found a need for it; I could use Dependency Injection and there would be benefits I suppose, but the benefits in my view wouldn't outweight the disadvantages such as the additional overhead.

    I don't think DI sits too well with the nature of PHP as a platform; Certainly there are people using DI but it's not common practice I've found. My impression is that it's just too heavy for what PHP is mostly used for, even for applications that were designed from the ground up to manage large volumes of data.

    I use factories to create class instances, and to encapsulate their dependencies, and this has worked well for a while now, so I can only suggest that whilst using DI, learn from it and consider other alternatives that give you the same advantages, more or less but without the ball and chain (that DI is in regards to PHP as a platform).

  6. #6
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is an area where I am in an active research mode.

    When I first encountered DI, I immediately liked the idea. That is the idea of passing dependencies into a class through the public interface, not necessarily the idea of the container. I've immediately implemented this as an API design technique.

    This has worked well for me at a low level library level where there are a few number of parameters, or you can pass an entirely different object to a class instead of a configuration parameter.

    You don't really need a DI container for this.

    This has worked less well at certain high level areas. For these, a service locator is SO much easier to setup and use. High level code isn't that reusable anyway.

    Originally, I thought I would need a general purpose DI container. I've looked at the ones available and written a couple prototypes of my own.

    However, I've come to believe that having a general purpose container is a case of speculative generality. The approach I'm taking now to move higher level code away from a Service Locator toward DI is to write a specialized "builder" or "serialization" class for each use case where I might use a DI container. I think fluent interfaces are especially appropriate for this.

    It may come to pass that after I've done this technique a few times, I may be able to extract out a general purpose DI Container. However, I don't think it will look very much like the current crop of DI containers in PHP. These seem mostly to be proofs of concept of a theory, rather than a tool borne of a practical need and observation. Second gen DI will differ much in the way that 2nd gen MVC frameworks like rails differ from first gen like struts.

    As for your performance problem, follow me on a journey.
    1. Reflection doesn't change much. You can cache this.
    2. One technique for caching that has been proven successful in PHP is to compile to PHP code and load that code. (Smarty)
    3. Imagine that you had a DI container that compiled to a PHP class.
    4. Imagine what that compiled class would look like.
    5. Now write that class by hand.
    6. Don't write the compiler.
    7. Don't Use a DI container.

  7. #7
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I never really understood the benefits of a full-size DI container as opposed to a simple "new $className()" call...

  8. #8
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fluent Interface Coupling? How would that process look like?
    First Run:
    $object->coupleMe()->serializeMe()->cacheMe()->methodCall();
    Second Run:
    Calling coupleMe would return coupled, serialized and cached $object?
    $object->coupleMe()->methodCall();
    Am I understanding this right?

    Is there any language with automatic wiring or dependency resolving?
    So in analogy to the command __autoload which loads files, why isn't there an command __autocouple or __autoresolve, which automatically resolves Classes and Interfaces for Constructor Injection.

    Which would mean, when Files are loaded they were reflected, Dependencies were resolved, the Object serialized and stuffed into a Cache. When the Object is accessed, it's fetched from Cache? Let's add an option for lazyresolving, which would mean, that Objects were autocoupled by first access? Maybe it's an ridiculous idea, but wouldn't that be faster as something similar written in PHP?

  9. #9
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > which automatically resolves Classes and Interfaces for Constructor Injection.

    More to the point, when PHP6 comes along with namespace support, what influence will that have on your Dependency solution?

    The worry about a cache is that it will at some point, become stale, which means that you have to maintain that cache; In the case of PHP and it's architecture (nothing lives, not even bacteria) will the effort really be worth it? Will it be worth the effort in regards that typically, most applications are aimed for small to mid scale usage.

    We all dream of developing a large scale, enterprise level application used by 10s of thousand of users over a number of continents, but just how realistic is that for most developers? For most applications? Let me put it another way then... I don't believe that you'll ever need something as heavy weight as DI.

    To do an implementation of one is bloat therefore, and bloatware doesn't scale

  10. #10
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    I don't believe that you'll ever need something as heavy weight as DI.

    Why does DI have to be heavy weight? I think Selkirk was on to something; why not just start with a registry class with hard coded methods for the objects in your app? Start with the simplest thing that possibly works, then refactor as needed. You'll need to wire your objects together somewhere, so why not do it all in one class?


    I think part of the problem here is trying to shoehorn a chunk of code that you don't quite understand that's designed to solve a problem that you don't quite have. Better to study the underlying pattern and apply what you need to the problems you do have, and see where that takes you.

  11. #11
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > You'll need to wire your objects together somewhere, so why not do it all in one class?

    I would say that is the option that I use at the moment; A Registry class with variable number of Factories which works as expected. However I urge that do we need a complete Dependency Injection framework in and of it's self for PHP?

    That is what I question, as I don't particularly believe that we need one, for the vast majority of cases this would be taking things to the extreme. Whilst what Selkirk has suggested makes sense, I'm not one for cache as that too has it's own concerns.

    Is there a solution that isn't bloated and at the same time, light weight? I'm not sure that currently there could be one that would have more advantages than disadvantages. But one good thing from this, is that the topic is still being discussed, and that ideas are being thrown about which can only be a good thing overall

  12. #12
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac View Post
    I never really understood the benefits of a full-size DI container as opposed to a simple "new $className()" call...
    If a class' dependencies changes (Eg. it's constructor signature changes), you'll have to rewrite all the new $className() calls. A container hides that coupling.

  13. #13
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Selkirk View Post
    These seem mostly to be proofs of concept of a theory, rather than a tool borne of a practical need and observation.
    As the author of Phemto, I can say that this is absolutely true . It was originally 50 lines of code written for a PHP Architect article on object construction.

    I've never used Phemto in anger myself. Not that I didn't originally have a need in my PHP code...it was developed further for a specific project that got canned (I needed to add memoisation to a bunch of classes to see if performance was improved). I haven't used Phemto since, because I haven't done a lot of PHP lately. Right now I'm using SQL and OCaml.

    That said, I am seriously collecting use cases. Please tell me what you want a DI container to do. Clearly lazy instantiation should be a given...

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  14. #14
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    If a class' dependencies changes (Eg. it's constructor signature changes), you'll have to rewrite all the new $className() calls. A container hides that coupling.
    That's why I try to avoid passing dependencies through constructor, instead relying on a public interface.

  15. #15
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    Is there a solution that isn't bloated and at the same time, light weight?
    Here's something I whipped up in about 10 minutes

    PHP Code:


    class Injector {

        private 
    $services;

        public function 
    __construct() {
            
    $this->services = array();
        }

        public function 
    register($service_name$class$args null) {
            if (
    is_null($args)) {
                
    $args = array();
            }

            if (!
    class_exists($class)) {
                throw new 
    Exception('The class '.$class.' does not exist');
            }

            
    $this->services[$service_name]  = array($class$args);

        }

        public function 
    get($service_name) {
            if (!isset(
    $this->services[$service_name])) {
                throw new 
    Exception($service_name.' is not a registered service');
            }

            list(
    $class$dependencies) = $this->services[$service_name];
            
    $arguments = array();

            foreach(
    $dependencies as $dependency) {
                
    $arguments[] = $this->get($dependency);
            }

            
    $reflection = new ReflectionClass($class);
            return 
    $reflection->newInstanceArgs($arguments);

        }

    }


    class 
    Foo {

        function 
    __construct() {

        }
    }


    class 
    Bar {

        var 
    $foo;

        function 
    __construct($foo) {
            
    $this->foo $foo;
        }
    }


    $injector = new Injector();

    $injector->register('foo''foo');
    $injector->register('bar''bar', array('foo'));
    $bar $injector->get('bar');

    assert(is_a($bar'bar'));
    assert(is_a($bar->foo'foo')); 
    That's about as lightweight as you can get. Obviously there's functionality missing, but that could be added as needed.

    Now, there's still the question of why you'd use something like this instead of simply wiring them together manually. It's hard to see the benefit with such a trivial example, but I think with a large object graph it makes things easier to maintain by cutting down the boiler plate and centralizing configuration.

  16. #16
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > Now, there's still the question of why you'd use something like this instead of simply
    > wiring them together manually.

    One route would be to have a Factory method on the class in question, and leave it to the class it's self to manage it's own dependencies? Maybe I'm just being stubborn (it has been known) but I'm still not convinced that what you get from it, is worth it.

    I would say it's down to the application at hand, on an per application level at that.

  17. #17
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac View Post
    That's why I try to avoid passing dependencies through constructor, instead relying on a public interface.
    I don't understand -- What do you mean by that? Do you mean to use a service locator?

  18. #18
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    One route would be to have a Factory method on the class in question, and leave it to the class it's self to manage it's own dependencies
    Dependency injection passes objects in. That's the whole point. The injectable class's behaviour can be changed simply by passing a different object to it.

  19. #19
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Pay attention. I said that was one route to take; It's an option, one of many. I didn't say that, that route was Dependency Injection.

    Put your glasses on the next time, -beep-

  20. #20
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    Dependency injection passes objects in. That's the whole point. The injectable class's behaviour can be changed simply by passing a different object to it.
    Moreover, being able to pass in different objects makes your classes easier to test with Mock objects, which is one of the main benefits of dependency injection.

  21. #21
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston View Post
    Pay attention. I said that was one route to take; It's an option, one of many. I didn't say that, that route was Dependency Injection.

    Put your glasses on the next time, -beep-
    I'm afraid I never really know what you're talking about any more than you.

  22. #22
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    33degrees, I just don't think foo/bar style examples are going move us from first generation DI containers (theoretical) to second (practical).

    Mr. Vain, could you post some examples of how you are using PicoContainer in your application. (or anyone using a DI container, please post REAL examples of use.)

    lastcraft, how many classes in a given app actually need lazy instantiation? I'm finding not so many. This can be handled on a case by case basis so the lazy gains aren't offset by container overhead.

    next use case, please.

    Please tell me what you want a DI container to do.
    I think this is the wrong question. how about...

    What problem does a DI container solve?

  23. #23
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Selkirk View Post
    What problem does a DI container solve?
    (1) provide a way to wire up an object graph
    (2) provide an easy way to configure the object graph

    This:
    PHP Code:
    $injector = new Phemto;
    $injector
        
    ->register('Foo')
        ->
    register(new Singleton('Bar'))
        ->
    register('Quark'); 
    ..is simpler to write than this:
    PHP Code:
    class Factory {

        function 
    getFoo() {
            return new 
    Foo(
                
    $this->_getBar());
        }
        function 
    _getBar() {
            if( !isset(
    $this->_bar)) {
                
    $this->_bar = new Bar(
                    
    $this->_getQuark(), 
                    
    $this->_getCharm());
            }
            return 
    $this->_bar;
        }
        function 
    _getQuark() {
            
    // ...
            // ...
        
    }
        function 
    _getCharm() {
            
    // ...
            // ...
        
    }

    The container knows how to fill dependencies and so I don't need to. The longer the cascade of dependencies of dependencies of etc... the nicer it will be to have that managed for you. If dependencies change, or if I want to change a lifecycle, there's a little less coding to do. Since I can trust the container to do its job I won't have a Factory unit test to write although to be fair for a dumb assembler that would only be a simple assertIsA sanity check.

    What has really made an impression on me so far is the second feature: provide an easy way to configure behaviour. Which of the two chunks of code above would you want to expose to end users?

    Quote Originally Posted by Selkirk View Post
    anyone using a DI container, please post REAL examples of use
    A couple of injectable policies are set here (StdTestCoveragePolicy & IdenticalTestReporterOutput). Briefly, Rephactor must decide if a refactoring has succeeded (by running tests), but also if there are any blind spots in the test coverage which would make the results an unreliable guide to success. I can explain more if you like; it's at an early stage and a bit of a mess in places. The point is Phemto allows the policies - whatever it is they do - to be changed easily without having to understand anything about the underlying code.

    Same sorta thing in this simple test extension: DataAccessTestCase. A pile of code dropped out when I first refactored to add Phemto and more would follow if it supported passing parameters to dependencies in an instantiate() call.

    To my mind a DIC like Phemto is an essential tool when there is a lot of wiring to be done and at least some of that needs to be made easily configurable. What would be a better solution?

  24. #24
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Selkirk View Post
    33degrees, I just don't think foo/bar style examples are going move us from first generation DI containers (theoretical) to second (practical).
    I think you missed the point I was trying to make, which is that a dependency injection framework does not have to be heavyweight or bloated. Dependency injection itself is a very simple concept, there's no reason why a framework that implements it should be complicated.

    As for moving from the theoretical to the practical, I think the problem comes in trying to envision how a DI framework should work, rather than extracting one from existing code.

    Quote Originally Posted by Selkirk View Post
    What problem does a DI container solve?
    Ultimately, the problem it solves is the same problem any other framework solves; it cuts down on repetitive code and makes your application easier to maintain. In the case of a DI container, the repetitive code is the code you use to wire your objects together, all those factory methods/classes that you write to decouple your dependencies. This is precisely what has gotten me interested in DI containers in the first place, looking at all the factory classes in my code and thinking there's got to be a better way of handling them.

  25. #25
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Selkirk View Post
    What problem does a DI container solve?
    Jeff, what problems do you, yourself, currently have?

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •