views:

494

answers:

7

I was working on my website written in php/mysql. When I first wrote it, it was spaghetti with lots of php embedded in html and the like - very hard to maintain.

I rewrote the whole thing with a nice modular structure with OOPS, and now it is much easier to maintain and expand.

But when testing the site performance using webwait and siege, the newer, better structured version seems to run and load slower than the spaghetti code version.

There's a difference of nearly 1 second in loading time - 2.39s vs 3.81s

Nothing else was changed except the php code - not the js, not the css

So what is the problem here? Should I revert back to the old code? Has this happened to others?

Edit:

  • I have done some analysis using cachegrind, inclued and I think the code is pretty good.
  • I also know that the problem is not entirely OOPS but the greater structure etc. and also that OOP doesn't at all guarantee better performance.
  • I have run the code multiple times too.
  • I've used cachegrind with kcachegrind, inclued, siege (most of the tools Rasmus lerdorf outlined in his drupalcon 2008 talk on 'Simple is Hard')

What I want to know is how others deal with this.

+6  A: 

Profile the code. I've no idea how one does that in PHP, but it's the only reasonable way to work out what's going on.

Sometimes making code more elegant will have a detrimental effect on performance, but not usually to that extent. You need to work out where the time's going, and fix that bit.

Jon Skeet
IIRC there is a surprisingly good profiler for PHP included in Zend Studio. It generates colourful charts too to impress the management.
DrJokepu
If you want to go the free route, here is a blogpost of mine explaining how to do it with XDebug: http://hype-free.blogspot.com/2008/06/profiling-php-with-xdebug.html
Cd-MaN
+1  A: 
There's a difference of nearly 1 second in loading time - 2.39s vs 3.81s

That is a difference of 3.81-2.39 = 1.42s which is over 50% of the smaller value so it isn't a small number to my mind. Have you run your tests multiple times so that an initial compilation/interpretation cost is being amortized properly? Have you considered trying to introduce timers to see where there is more time being taken than before? Those would be my suggestions as it seems you may have introduced a lot of abstraction and are now seeing the price for that.

JB King
+14  A: 

"Should I revert back to the old code?"

If I say revert, you'll say "see, I knew OO was a blown unit, no one can make an OO application that works." That would be wrong.

If I say don't revert, you'll say, "but it's unacceptably slow."

So, what's left?

You have to write it better. Go forward. Rewrite your OO so that it actually works. OO isn't "magic" -- it doesn't guarantee anything. There are bad OO programs and good OO programs. In your case, you obviously have room for improvement.

So get some performance profiling tools and find out where the time has gone.

Also, don't "optimize" -- rewrite.

Odds are very good that you have some kind of search going on that takes up a lot of time. Eliminate search. Use better containers and collections (hash maps, sets, etc.)

S.Lott
+1 - maintainability and performance are orthogonal - one doesn't imply the other and vice versa
DanSingerman
+1  A: 

Try setting up Xdebug and seeing what it can tell you. Someone else mentioned that you should check it out with a profiler. I agree, and Xdebug can provide you with one as well as some other useful functionality. Your IDE of choice may even integrate with Xdebug.

Jeremy DeGroot
A: 

One thing to consider: are you using APC or some other PHP opcode caching solution? If not, all your code is being re-interpreted from scratch every time you load a page. This could definitely affect performance.

Chad Birch
But the relative performance difference will be the same right?
trex279
Not necessarily, your new OO code may require more complex interpretation than the previous code did.
Chad Birch
Not necessarily. APC offsets the cost of include() and require() but doesn't make the actual computations load faster. An OO application will, most likely, have to include a lot more code on every page, even if it's never run.
Sean McSomething
A: 

OOP means a lot of function calls, and function calls in dynamic languages are slow. So "translating" old code into OOP version will slow it down. Do a complete rewrite.

vartec
Can you explain a bit more on what I should focus on during the rewrite?
trex279
Do not create classes in excess. Especially do not create classes that you'll use only in one of the methods.Anyway, as it's been already said, OOP does not make your code run faster. It makes it more reliable and easier to develop and maintian. To accelerate use APC (you can cache some objects)
vartec
+1  A: 

I can think of a couple of points to consider:

  • It's not a choice of OOP vs spaghetti code. There are other paradigms that may be just as maintainable and structured as OOP, but with different performance characteristics. It is possible to write OOP code using only simple procedural language features (many big C frameworks use a very OOP-ey style.) A more functional style may also be simpler in some cases. OOP isn't the One True Paradigm.
  • There are different degrees of OOP. Modelling data as objects does not in most languages cause a noticeable performance difference (I don't know how PHP performs in this area, though, but with PHP I always expect the worst). However, virtual functions, inheritance (and especially multiple inheritance) are slower and add overhead that often could have been avoided. Which OOP features do you use? Is there a simpler OOP design that would do the job, but with less reliance on "slow" language features?

On top of that, the usual obviously applies (can you optimize the algorithm, enable caching or precompilation, and so on - but while those may help dramatically, they're not specific to OOP)

jalf