Topic: Some test results (PHP OOP vs Procedural vs "Nothing")

I was browsing the web to find out the efficiency of OOP vs Procedural in PHP and came across this test. It seemed to be missing some extra tests, soes here's my results (P4 2.8G Hyper-Threading, 2x512 Duel Channel RAM, PHP v5.1.6).

test.php:

<?php

define('REPEAT',        10000000);
define('REPEAT_DIV_10',    1000000);

class test
{
    function one()
    {
        return 1;
    }
}

function one()
{
    return 1;
}

$results[] = time()."\n";

for ($i=0; $i<REPEAT; $i++)
{
    $testclass=new test();
    $cnt+=$testclass->one();
}

$results[] = time()."\n";

$testclass=new test();
for ($i=0; $i<REPEAT; $i++)
{
    $cnt+=$testclass->one();
}

$results[] = time()."\n";

for ($i=0; $i<REPEAT; $i++)
{
    $cnt+=one();
}

$results[] = time()."\n";

for ($i=0; $i<REPEAT; $i++)
{
    $cnt+=1;
}

$results[] = time()."\n";

for ($i=0; $i<REPEAT_DIV_10; $i++)
{
    $testclass=new test();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
}

$results[] = time()."\n";

$testclass=new test();
for ($i=0; $i<REPEAT_DIV_10; $i++)
{
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
    $cnt+=$testclass->one();
}

$results[] = time()."\n";

for ($i=0; $i<REPEAT_DIV_10; $i++)
{
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
    $cnt+=one();
}

$results[] = time()."\n";

for ($i=0; $i<REPEAT_DIV_10; $i++)
{
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
    $cnt+=1;
}

$results[] = time()."\n";

for ($i=0;$i+1<sizeof($results);$i++)
{
    echo "Results ($i):\t".($results[$i+1] - $results[$i])."\n";
}
 $ php ./temp.php 
Results (0):    18
Results (1):    9
Results (2):    8
Results (3):    4
Results (4):    7
Results (5):    6
Results (6):    5
Results (7):    1
 $ php ./temp.php 
Results (0):    18
Results (1):    9
Results (2):    9
Results (3):    4
Results (4):    7
Results (5):    6
Results (6):    5
Results (7):    1
 $ php ./temp.php 
Results (0):    17
Results (1):    9
Results (2):    8
Results (3):    4
Results (4):    7
Results (5):    6
Results (6):    5
Results (7):    0
 $ php ./temp.php 
Results (0):    17
Results (1):    9
Results (2):    8
Results (3):    4
Results (4):    7
Results (5):    6
Results (6):    5
Results (7):    1
 $ php ./temp.php 
Results (0):    17
Results (1):    9
Results (2):    8
Results (3):    4
Results (4):    7
Results (5):    6
Results (6):    5
Results (7):    1

Result 0 is creating an object each time the function is called. Rightly so, it's terribly slow.

Result 1 is creating an object once, and then calling a function each loop. It's usually about 1 second slower then Result 2. I'm guessing that's the overhead on calling an object's function (not 1 second, but probably around 1 / RESULT seconds per call). This is not the overhead of creating an object the first time since the object was created the first time in Result 0 (also, just to make sure this "first time" creation didn't affect Result 0, I commented out everything but the Result 0 code, then 1, etc... and got the same times).

Result 2 is calling a function each loop. a touch faster then using the object, but does not seem significant.

Result 3 is not making any calls. About 2x faster then using functions, but also much harder to read/maintain (in medium/large projects).

Result 4 is creating an object every 10 function calls. It calls the function the exact same amount of times as Result 0 (or 1 or 2 or 5 or 6 for that matter tongue), but creates the object 10 times less often. Comparing these results to 0 through 3 it would seem that the for loop has it's own overhead. It would also seem that object creation has significant overhead when done often.

Result 5 is creating an object once, and calling the function the same amount as results 1 (or 0 or 2 or 4 or 6 for that matter tongue). Again we see about 1 second overhead when calling an objects function.

Result 6, same amount of function calls, just done with less loops.

Result 7... OMG... if only we didn't need to call functions, eh? from 5 seconds to 0! Course you'd have to leave out loops too (Result 3, doing the addition once per loop was 4 seconds). Be interesting to see a php "compiler" that just parsed out function calls and loops at the cost of file size.

Conclusions: It's not that costly to use a few "Global objects" that are only created once each page hit, and are used in a few places in that pages code. Any objects that need to be re-created often will probably start showing their cost, and could be optimized by using procedural function calls instead (or using a single object to do the job of the multi-creation object class). If your worried about the 1 second overhead (or less/more? php's time() probably isn't the best score card tongue), then you should also be worried about the overhead of loops and function calls. Result 3 vs Result 7 was only 10 times less loops, but was 4 times faster in the second set. Note to self: Write a script to parse out functions, classes, and loops, then spit out unintelligible non-OOP, non-procedural php, from an intelligible php source smile

Hope this helps yous in some way, I learnt something... I think... 0.o

echo "deadram"; echo; fortune;

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

You're bored, aren't you? tongue

Nice test.

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

time()? use microtime() tongue

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

@elbekko Nah, needed to weight the cost of procedural vs OOP in php and perl. One of my side projects needs efficient code, but will end up being a large project (so needs good self documenting code). I've ended up going with perl "singleton" objects. php lost out for lack of efficient regex support and lack of scope control. Might kick myself in the butt in a few years when php becomes a little more mature though.

@Smartys aww crap, stupid "I'm feeling lucky" hits when searching php doc's smile

echo "deadram"; echo; fortune;

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

you're using your objects like procedural statements.  oop isn't going to do anything for you in that scenario.  one thing I'd be interested in is seeing the performance difference in a real application.  a good sample would be to create code that hits a database, pulls records and posts them to a table.  the procedural one would need to do the normal steps, and the oo one on object creation would hit the database and give you access to the data through the object.

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

  This isn't a "OOP is worse then procedural" benchmarks. It messures time spent creating an object with a single function, time spent calling an object's function, time spent calling a function, and time spent without either. It offers nothing conclusive for all senarios, but does hint at places where one might improve speed. Each program/script is different, and each programmer's (or clients) needs are different.

  I'm not really using my object period, or my function. I'm timing the underlying system. No matter how neat and inovative my OOP code may be, it won't outperform 18 seconds for 10000000 creations on my box+config+version of php. I'm also willing to bet that regardless of box+config the ratio of 18:9:8:4 will remain constant, and regardless of version (ignoring other majors though, php6 for example tongue) the ratio will remain fairly simular. I don't think I mentioned anything about what oop could or couldn't do... I simply mentioned how fast it could execute under 2 different senarios.

  I think it's important to keep in mind that no benchmark will ever tell the whole story, short of writing the app twice, but who really has time for that tongue PS: Appologies for the spelling, don't have firefox atm, and opera doesn't have spellcheck installed by default? 0.o

echo "deadram"; echo; fortune;

7 (edited by orlandu63 2007-03-11 07:12)

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

deadram wrote:

  This isn't a "OOP is worse then procedural" benchmarks. It messures time spent creating an object with a single function, time spent calling an object's function, time spent calling a function, and time spent without either. It offers nothing conclusive for all senarios, but does hint at places where one might improve speed. Each program/script is different, and each programmer's (or clients) needs are different.

  I'm not really using my object period, or my function. I'm timing the underlying system. No matter how neat and inovative my OOP code may be, it won't outperform 18 seconds for 10000000 creations on my box+config+version of php. I'm also willing to bet that regardless of box+config the ratio of 18:9:8:4 will remain constant, and regardless of version (ignoring other majors though, php6 for example tongue) the ratio will remain fairly simular. I don't think I mentioned anything about what oop could or couldn't do... I simply mentioned how fast it could execute under 2 different senarios.

  I think it's important to keep in mind that no benchmark will ever tell the whole story, short of writing the app twice, but who really has time for that tongue PS: Appologies for the spelling, don't have firefox atm, and opera doesn't have spellcheck installed by default? 0.o

On a totally unrelated note: People actually use spellcheck? Lazy lazy.

Re: Some test results (PHP OOP vs Procedural vs "Nothing")

I'll iliteerate. Whit oot speel cheke i cane't rite.

echo "deadram"; echo; fortune;