Procedural PHP leads to slower apps

After reading OOP and Performance, Christopher Thompson rightly called my bluff (see the comments), triggering further discussion and forcing me to think harder.

In “OOP and Performance” I wasn’t trying to say anything absolute but rather describe a general hunch I’ve got. Although I singled out two personal examples, where the effect can, and was, written off as implementation detail, the hunch actually comes from general impressions and memories of trawling the source code of Open Source PHP apps, over the years, where they were written primarily with procedural code. And it’s not to say there aren’t any dog-slow OO apps out there – there most definately are.

Anyway, rather than waffle on further, I’m going to stick my neck out and say procedural PHP leads to slower apps (so I can get it chopped off ;)). The reason I’m feeling confident is that I think I’ve got a challenge which will help make things self-evident. Side note to any Perl / Python / whatever programmers – to an extent think this is specific to PHP, where a script itself does not define a separate variable scope and where classes are the only clean way to build abstractions.

So here goes. I’m going to define the input and output of a single script by providing the top and bottom. If you’ve got the time / interest,humour me and implement the section in the middle, once without using classes and a second time using classes / OO.

At the top of this script we have;


// This first dataset
$dataset1 = array();
for($i = 0; $i < 100; $i++ ) {
$dataset1[] = array('a','b','c');
}

// This second dataset
$dataset2 = array();
for($i = 0; $i < 100; $i++ ) {
$dataset2[] = array(
'x'=>array(1,2),
'y'=>array(3,4),
'z'=>array(5,6),
);
}

// This variable controls how the output is rendered
// Allowed values 'html','xml', 'plain'
$output_type = 'html';

(Your code goes in here)

…then at the bottom we have;


// output place in this variable
echo $result;

Of course there’s some rules and requirements…

The Requirements

- $dataset1 should be displayed to the user above $dataset2

- the script must be capable of rendering HTML, XML and plain text (whitespace formatted), depending the value of the output variable

- each dataset should be displayed with some kind of header (like a table caption) that tells the user what it is.

The Rules

- you may not include any external PHP scripts – it must be all in a single script

- you may not read or write to any external files (in particular you can’t use templates or code generation)

- placing function names in variables comes under the heading “hack”, as does using PHP’s create_function()

- nothing should be output until the final statement: echo $result;

- try to code as quickly as possible – don’t spend too much time thinking about the solutions.

- don’t do any benchmarking until you’ve finished

Despite the rules, I think this example is fairly representative of the type of code that makes up big parts of typical PHP apps.

In fact I’m actually expecting someone to come up with a procedural solution which benchmarks fastest overall, but not by much. At the same time I think this will illustrate why it’s more likely that procedural code ends up delivering relatively poor performance.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Sebastian

    //Q// – try to code as quickly as possible – don’t spend too much time thinking about the solutions.
    // Q //

    Thats a easy way to get unsmart solutions .. how will you control this ????

    //Q// don’t do any benchmarking until you’ve finished
    //Q//
    How will you control that ?

    //Q//
    placing function names in variables comes under the heading “hack”, as does using PHP’s create_function()
    //Q//

    why that ???

    Sebastian

  • Ian Bicking

    Can you give an example of the output, because it’s kind of vague given the abstract data…?

  • neves

    Nice mini contest :)
    What about the output? I’ll choose layout of each one?

  • arborint

    Everything except: “placing function names in variables comes under the heading ‘hack’,”. PHP not only provides support for this (call_user_func), plus also provides error checking support as well (is_callable). Hardly a hack.

  • http://www.lastcraft.com/ lastcraft

    Well done Harry.

    Nice to see you not only stick to your guns, but to actually come out fighting. I think your a dead man, but very a courageous one :).

    yours, Marcus

  • Dr Livingston

    I think this was intended as a bit of fun? Folks have been argueing for years that OO is slower than procedural, and vice versa.

    If on the other hand this is meant to be serious then sorry harry, but I think it’s pointless, from the point of view of the arguement that is – it’s obvious OO is faster ;)

  • arborint

    Harry, with your neck stuck out like that you look funny. Seriously, I think you are on to something interesting and skipping the “challenge” would be fine. Mainly because there is really no one to convince. I may play Devil’s Advocate frequently (my apologies to Marcus for all past and future pestering), but I think you’re on a roll.

    Your original premise was that using a methodology that helps you more clearly see the actual meaning and behaviour of the logic with produce better code. Your said, “My feeling was that if the author had been thinking in terms of useful abstractions…” You are definitely on to something, but then people like me are going to ask you to clarify “actual” in “actual meaning and behaviour of the logic” and “useful” in “useful abstractions.” The reason this is important is that the designers of bad code do come up with meaning, behaviour and abstraction too. They just don’t get it right.

    So my question is: What helps PHP programers get it right? I am hoping that in your next article you will show how a programmer might solve your challenge in better or worse ways specifically in PHP, and then analyze.

    Christopher

    PS – As an OO programmer who is not of the “OOP is just superior” persuasion, I hope you can break free of the OOP vs Procedural dogma and dive into practical PHP design and development. Your challenge can be implemented well or poorly in OOP, Procedural or a mixed implementation. It’s the better design that interests me.

  • Anonymous

    It is a nice challenge but still too many people taking it too seriously..

  • patrikG

    Your challenge can be implemented well or poorly in OOP, Procedural or a mixed implementation. It’s the better design that interests me.

    Yes, but that’s not the point. To my mind, Harry challenges only(!) the perceived axiom that OOP is inherently slower than procedural programming.

    The result will probably be what you are saying aborint, but at the same time, it’s the way that matters, even if the goal is known.

  • http://mgaps.highsidecafe.com BDKR

    To my mind, Harry challenges only(!) the perceived axiom that OOP is inherently slower than procedural programming.

    There is nothing perceived about that. A method call is slower than a function. Incrementing a member variable is slower than just a plain old var in the global scope. And so on…

    But that’s not what’s in contention here.

    I really suspect that we are talking about something a little more subtle which surrounds Harrys thrust that an OO developer is more likely to come up with a superior performing app. Not becuase he’s using OO, but becuase of something else that we have a tendency to believe only OO developers are capable of.

    Object Oreinted Design.

    In terms of responsibility, one that uses OOD may be more likely to see at a higher level what areas of his/her logic are slow, or perhaps even redundant. As in the case of an example in his previous blog entry, it appears that (please correct me if I understood the example wrong) the procedural logic had multiple functions that all acted on the same data set one right after the other. Now perhaps if one could zoom out a bit they would be more likely to see that there is redundance in iterating over that same data with each function call.

    From his previous blog entry:

    My feeling was that if the author had been thinking in terms of useful abstractions, the inefficiency of looping through the entire dataset each time would have stood out. Instead they’d been stuck knee deep in the code too long to be able to see the bigger picture.

    Now consider one of the requirements that Harry put down on the challenge associated with this entry.

    – try to code as quickly as possible – don’t spend too much time thinking about the solutions.

    This requirement, if you ask me, is designed to weed out the coders, regardless of methodology, that haven’t yet learned how to view the overall logic at a higher level.

    What is troubling is that it’s his idea that this is a problem primarily with procedural coders (and is what he is hoping to prove with this contest). But it’s easy to see that an OOP guy could just as easily have created multiple classes to act as filters of different types then implement them in the same way those functions are in the procedural version.

    The real problem is one of design. However, that issue of design at a high level becomes an algorithmic question right? How do I best organize all of these running objects in the most effecient manner?

    Going back to this quote:

    My feeling was that if the author had been thinking in terms of useful abstractions, the inefficiency of looping through the entire dataset each time would have stood out.

    While it’s obvious I agree with Harry about this, I don’t agree with the language and it’s implication. It’s my opinion that the act of creating a function (that can also be re-used) is abstracting that functionality away behind the functions name (which is a flat out awesome way to read code). The problem here is one of level or altitude. Once the OOP or Procedural developer has figured out what he needs in terms of functionality and has created that, he can and should zoom out or up and take an orginazational view of the entire operation.

    Begins to sound a lot like the stuff that’s done to help manufacturing operations become more effecient. First identify all of the operations and support mechanisms then scrutinize their organization.

    Oh well…

    P.S. Could we please have a preview button?

  • Tribalist

    What is a lot more interesting than the actual topic, is that this is a superb example of tribalism. (Going meta is always fun!)

    You identify “your own group” with the positive figures, those that know how to do it right and conveniently blend out all the “failures”, since those don’t belong to the group yet – they’re doing wrong. (Also see “no true scotsman fallacy”)
    Whereas the opposite group is always identified by their worst members – low-lifes, thugs, rapists, spaghetti-coders.

    Please forgive my trolling. Have a read at this timeless article:
    http://www.perl.com/pub/a/2000/12/advocacy.html

    It’s only superficially about programming languages, it applies in much the same way to programming methodologies.

  • arborint

    To my mind, Harry challenges only(!) the perceived axiom that OOP is inherently slower than procedural programming.

    I think you confuse speed of statements versus speed of applications. People believe the axiom that some OO language constructs are slower because they measurably are slower (while is what the article that got Harry started showed). But the speed of individual language constructs has much less to do with application performance than good design. Choosing some slower statements so that your program is easier to build, change or extend is often a wise decision and usually does not have a significant impact on performance, especially given the benefits in the build, change or extend areas.

    Christopher

  • MickoZ

    I have tried to code really fast, withouth thinking. Of course doing the OOP second, give you an advantage. To do a real test, you might want to do mixed study (OOP first, Procedural second, etc.)

    I am tempted to risk myself and just post what I typed in some minutes. So I can be analyzed. Of course if beside put around 5-10 minute and thought, it will be nice. But then it also depends the need. If the need is like a programming contest where all that matter is speed of coding… in that case it changes. If the goal is to design to change later, it depends… sometime just rewritting the whole stuff is faster ;-)

    However, I think I would risk to post my code just so you analyze how I did it (and yes I copy pasted my rendering code), yes I could have made one function that display a result set. I tried to understand the problem fast, etc. I migth not have understood it as intended by the author ;-) Ok enough babbling, I copy paste my code (first procedural, second OOP and I am not an amazing OOP coder… I rarely do factory stuff, but I tried to do one now.. I might have had it wrong, and I don’t care, I want to see what the comments will be!):

    Procedural:


    < ?php
    // This first dataset
    $dataset1 = array();
    for($i = 0; $i < 100; $i++ ) {
    $dataset1[] = array('a','b','c');
    }

    // This second dataset
    $dataset2 = array();
    for($i = 0; $i < 100; $i++ ) {
    $dataset2[] = array(
    'x'=>array(1,2),
    'y'=>array(3,4),
    'z'=>array(5,6),
    );
    }

    // This variable controls how the output is rendered
    // Allowed values 'html','xml', 'plain'
    $output_type = 'plain';

    //---------------------------------------------------------------------
    // BEGIN CODE
    //---------------------------------------------------------------------

    $result = display($output_type, $dataset1, $dataset2);

    //---------------------------------------------------------------------
    // END CODE
    //---------------------------------------------------------------------

    // output place in this variable
    echo $result;

    //---------------------------------------------------------------------
    // PROCEDURAL FUNCTIONS
    //---------------------------------------------------------------------

    function display($output_type, $dataset1, $dataset2)
    {
    switch($output_type)
    {
    case 'html':
    $result = display_html($dataset1, $dataset2);
    break;
    case 'xml':
    $result = display_xml($dataset1, $dataset2);
    break;
    case 'plain':
    $result = display_plain($dataset1, $dataset2);
    break;
    default:
    $result = display_html($dataset1, $dataset2);
    break;
    }

    return $result;
    }

    function display_html($dataset1, $dataset2)
    {
    $result = "";

    $result .= "

    dataset1

    ";
    $result .= "

    ";
    foreach ($dataset1 as $row)
    {
    $result .= "
    ";
    foreach ($row as $column)
    {
    $result .= "

    ";
    }
    $result .= "

    ";
    }
    $result .= "

    ".htmlspecialchars($column)."

    ";

    $result .= "

    dataset2

    ";
    $result .= "

    ";
    foreach ($dataset2 as $row)
    {
    $result .= "
    ";
    foreach ($row as $column)
    {
    $result .= "

    ";
    }
    $result .= "

    ";
    }
    $result .= "

    ".htmlspecialchars($column[0]).",".htmlspecialchars($column[1])."

    ";

    return $result;
    }

    function display_xml($dataset1, $dataset2)
    {
    $result = "";

    $result .= "

    ";
    foreach ($dataset1 as $row)
    {
    $result .= "";
    foreach ($row as $column)
    {
    $result .= "".$column."";
    }
    $result .= "
    ";
    }
    $result .= "

    ";

    $result .= "

    ";
    foreach ($dataset2 as $row)
    {
    $result .= "";
    foreach ($row as $column)
    {
    $result .= "".$column[0].",".$column[1]."";
    }
    $result .= "
    ";
    }
    $result .= "

    ";

    return $result;
    }

    function display_plain($dataset1, $dataset2)
    {
    $result = "";

    $result .= "dataset1n";
    $result .= "--------n";
    foreach ($dataset1 as $row)
    {
    foreach ($row as $column)
    {
    $result .= $column."|";
    }
    $result .= "n";
    }
    $result .= "nn";

    $result .= "dataset2n";
    $result .= "--------n";
    foreach ($dataset2 as $row)
    {
    foreach ($row as $column)
    {
    $result .= $column[0].",".$column[1]."|";
    }
    $result .= "n";
    }
    $result .= "nn";

    return $result;
    }
    ?>

    OOP:


    < ?php
    // This first dataset
    $dataset1 = array();
    for($i = 0; $i < 100; $i++ ) {
    $dataset1[] = array('a','b','c');
    }

    // This second dataset
    $dataset2 = array();
    for($i = 0; $i < 100; $i++ ) {
    $dataset2[] = array(
    'x'=>array(1,2),
    'y'=>array(3,4),
    'z'=>array(5,6),
    );
    }

    // This variable controls how the output is rendered
    // Allowed values 'html','xml', 'plain'
    $output_type = 'xml';

    //---------------------------------------------------------------------
    // BEGIN CODE
    //---------------------------------------------------------------------

    $renderer = RendererFactory::getRenderer($output_type, $dataset1, $dataset2);
    $result = $renderer->getResult();

    //---------------------------------------------------------------------
    // END CODE
    //---------------------------------------------------------------------

    // output place in this variable
    echo $result;

    //---------------------------------------------------------------------
    // FUNCTIONS
    //---------------------------------------------------------------------

    class RendererFactory
    {
    function getRenderer($output_type, $dataset1, $dataset2)
    {
    $renderer = null;

    switch ($output_type)
    {
    case 'html':
    $renderer = new HtmlRenderer($dataset1, $dataset2);
    break;
    case 'xml':
    $renderer = new XmlRenderer($dataset1, $dataset2);
    break;
    case 'plain':
    $renderer = new PlainRenderer($dataset1, $dataset2);
    break;
    default:
    $renderer = new HtmlRenderer($dataset1, $dataset2);
    break;
    }

    return $renderer;
    }
    }

    class Renderer
    {
    var $dataset1;
    var $dataset2;
    var $result;

    function Renderer($dataset1, $dataset2)
    {
    $this->dataset1 = $dataset1;
    $this->dataset2 = $dataset2;
    }

    function getResult()
    {
    if (!isset($this->result))
    {
    $this->render();
    }

    return $this->result;
    }

    function render()
    {
    $this->result = "";
    }
    }

    class HtmlRenderer extends Renderer
    {
    function HtmlRenderer($dataset1, $dataset2)
    {
    parent::Renderer($dataset1, $dataset2);
    }

    function render()
    {
    $result = "";

    $result .= "

    dataset1

    ";
    $result .= "

    ";
    foreach ($this->dataset1 as $row)
    {
    $result .= "
    ";
    foreach ($row as $column)
    {
    $result .= "

    ";
    }
    $result .= "

    ";
    }
    $result .= "

    ".htmlspecialchars($column)."

    ";

    $result .= "

    dataset2

    ";
    $result .= "

    ";
    foreach ($this->dataset2 as $row)
    {
    $result .= "
    ";
    foreach ($row as $column)
    {
    $result .= "

    ";
    }
    $result .= "

    ";
    }
    $result .= "

    ".htmlspecialchars($column[0]).",".htmlspecialchars($column[1])."

    ";

    $this->result = $result;
    }
    }

    class XmlRenderer extends Renderer
    {
    function XmlRenderer($dataset1, $dataset2)
    {
    parent::Renderer($dataset1, $dataset2);
    }

    function render()
    {
    $result = "";

    $result .= "

    ";
    foreach ($this->dataset1 as $row)
    {
    $result .= "";
    foreach ($row as $column)
    {
    $result .= "".$column."";
    }
    $result .= "
    ";
    }
    $result .= "

    ";

    $result .= "

    ";
    foreach ($this->dataset2 as $row)
    {
    $result .= "";
    foreach ($row as $column)
    {
    $result .= "".$column[0].",".$column[1]."";
    }
    $result .= "
    ";
    }
    $result .= "

    ";

    $this->result = $result;
    }
    }

    class PlainRenderer extends Renderer
    {
    function PlainRenderer($dataset1, $dataset2)
    {
    parent::Renderer($dataset1, $dataset2);
    }

    function render()
    {
    $result = "";

    $result .= "dataset1n";
    $result .= "--------n";
    foreach ($this->dataset1 as $row)
    {
    foreach ($row as $column)
    {
    $result .= $column."|";
    }
    $result .= "n";
    }
    $result .= "nn";

    $result .= "dataset2n";
    $result .= "--------n";
    foreach ($this->dataset2 as $row)
    {
    foreach ($row as $column)
    {
    $result .= $column[0].",".$column[1]."|";
    }
    $result .= "n";
    }
    $result .= "nn";

    $this->result = $result;
    }
    }

    ?>

    ASM-PHP:


    asm {
    mov $crap,"Just kidding!"
    }

    echo $crap;

    It mights have been just a joke, but let’s see how my naivety with this one will go.

    But then if it is about structuring an apps and OOP help, the performance issue, it really depend. ;-) If you got a 100 hits/day website… and a 4 trillions zillions hits / day website. There might be thing to consider…

    We of course can do the same code for both. (ex: I did a kind of caching mecanism in the OOP version just for the sake of it, I could have done the same in procedural… I tried to let away my perfectionnist side and just do it(c))

    Enjoy and I cannot wait to see the comments ;-)

  • arborint

    Well, I think you have given us, in one fell swoop, good evidence that:

    - Harry is correct that Procedural produces worse code
    – that OOP is slower and Harry is dead man, but very a courageous one.
    – That we should go for good design first and then refactor for performance as necessary

    MickoZ, I would suggest having a go at reimplementing your code to have a single renderer for all data, and different code to do the actual formating. In this case the formaters would have functions like: getHeader(), getRow() and getFooter(). I also think you should ignore Harry’s restriction on “placing function names in variables”. Try doing the Procedural first again.

    Christopher

  • http://mgaps.highsidecafe.com BDKR

    [QUOTE]
    What is a lot more interesting than the actual topic, is that this is a superb example of tribalism. (Going meta is always fun!)

    You identify “your own group” with the positive figures, those that know how to do it right and conveniently blend out all the “failures”, since those don’t belong to the group yet – they’re doing wrong. (Also see “no true scotsman fallacy”) Whereas the opposite group is always identified by their worst members – low-lifes, thugs, rapists, spaghetti-coders.

    Please forgive my trolling. Have a read at this timeless article: http://www.perl.com/pub/a/2000/12/advocacy.html

    It’s only superficially about programming languages, it applies in much the same way to programming methodologies.
    [/QUOTE]

    You are right on the money! And that’s a great read too. As for that last quote, my guess is Larry Wall, who I think is awesome! Two points? :-)

    Cheers

  • http://www.realityedge.com.au mrsmiley

    Dont hear me wrong, I’m all for using the best tool for the job. Lately I’ve started using a healthy blend of procedural and OO design to get the job done. Use the strengths of PHP where they are best suited.

    That said, the above test is biased towards creating an OO solution faster? Why, because as per the rules of engagement, you have to code it first proceduraly, then go OO style. Hence, you’ve already thought about the problem BEFORE you even get to the OO method.

    A better test would be have two, and reverse the order that you code them. Eg. Test 1, procedural then OO, Test 2, OO then procedural.

  • http://www.phpnerds.com petesmc

    Exactly what type of output is expected? Just write out the arrays? Like:

    Row 1: a=1 b=2 c=3 ??

    html:

    Row 1: a=1 …etc ??

    This needs to be explained better. On a side note, the procedural will be faster in my opinion. Alot of us who can write OOP code can already abstract in our heads as well as find logically the fastest method of a script execution.

  • MickoZ

    arboint: yeah, I actually though of a lot of way to do it. I just tried to follow the “rule” to try to do it fast.

    It also always depend of the need somehow. I can be a maniac about how things is done. But if all I receive is data (and those two dataset are not the same format) and all I have to do is output them, and I have to do it in less than 20 minutes. I will try to not fall into the “what if, what if”, I will take a solution to make it works. And as soon as I finished “speed-coding”, I was wondering if I should not have gone with a class that describe the dataset, which I instanciate with a header, blah blah. I could have done the same in procedural.

    Like it is fun in procedural to code with structure and fonction. Which somehow get very near OOP (not 100% the same, but it just divide thing to make it clearer).

  • arborint

    So Harry? You said, “I’ve got a challenge which will help make things self-evident.” I think I need a little help clarifying your PHP hypothesis about variable scope and clean abstractions.

    Christopher

  • http://www.gandullia.com jgandu

    This should really be Benchmarked on PHP 5 where the re-vamped object model improves OOP performance.

  • Steve

    In a nutshell, Harry’s argument is this: the nature of object oriented code naturally leads skilled developers to see and avoid areas of inefficiency in PHP scripts

    Should this actually read inefficient developers aren’t skilled enough to write good code. It’s got nothing to with OOP…

    A SKILLED developer can write excellent procedural code and like OOP, once written and tested properly, it works.

    Even OOP can be made inefficient…

    To my mind, with 15 years of cutting code from ASM to C to Pascal to Cobol to Basic in functions procedures, whatever, INSTINCT ensures that procedural code is efficient and a well built library is too good a tool to ditch for a new methodology. If it ain’t broke…

    And I’m talking SPEED here too… Of development, where it’s REALLY at when you’re client is on the phone asking about that impossible deadline he’s set.

    “Oops…” is not an excuse come payday :)

  • rick_g22

    Question. Why does it have to be EITHER / OR, why not BOTH / AND ? It doesn’t have to be _ALL_ objets, or _NO_ objects at all. I’m not trying to break my head by designing EVERYTHING with object and turning it into a java-like maze – or making everything like spaguetti by using procedural-only PHP.

    I have a framework which uses Brian Lozier’s Template class, _AND_ global functions. I agree, the global function namespace gets a bit cluttered, but it can be managed. I just include the necessary files, and everything works fine. Best of both worlds.

  • simonu

    From first principles, the best piece of OO code is going to be slower than the best piece of non-OO. Simple due to the extra overhead involved in creating and managing the objects. It doesn’t matter if you use PHP5 or PHP55 – there is always going to be more overhead. Isn’t there?

    Having said that I realise the debate here is whether OO techniques lead to a better design approach and therefore more efficient (and faster) code.

    Again I believe in terms of code speed, non-OO is going to win.

    Here’s my attempt at the challenge:


    switch($output_type)
    {
    case 'xml':
    $result="

    n";
    for ($y=0;$y<100;$y++) $result.="".$dataset1[$y][0]."".$dataset1[$y][1]."".$dataset1[$y][2]."n";
    $result.="

    n

    n";
    for ($y=0;$y<100;$y++) $result.="".$dataset2[$y]['x'][0].",".$dataset2[$y]['x'][1]."".$dataset2[$y]['y'][0].",".$dataset2[$y]['y'][1]."".$dataset2[$y]['z'][0].",".$dataset2[$y]['z'][1]."n";
    $result.="

    n";
    break;
    case 'html':
    $result="

    dataset1

    ";
    for ($y=0;$y<100;$y++) $result.="

    ";
    $result.="

    ".$dataset1[$y][0]." ".$dataset1[$y][1]." ".$dataset1[$y][2]."

    dataset2

    ";
    for ($y=0;$y<100;$y++) $result.="

    ";
    $result.="

    ".$dataset2[$y]['x'][0].",".$dataset2[$y]['x'][1]." ".$dataset2[$y]['y'][0].",".$dataset2[$y]['y'][1]." ".$dataset2[$y]['z'][0].",".$dataset2[$y]['z'][1]."

    ";
    break;
    case 'plain':
    default:
    $result="dataset1n--------n";
    for ($y=0;$y<100;$y++) $result.=$dataset1[$y][0]."|".$dataset1[$y][1]."|".$dataset1[$y][2]."n";
    $result.="nndataset2n--------n";
    for ($y=0;$y<100;$y++) $result.=$dataset2[$y]['x'][0].",".$dataset2[$y]['x'][1]."|".$dataset2[$y]['y'][0].",".$dataset2[$y]['y'][1]."|".$dataset2[$y]['z'][0].",".$dataset2[$y]['z'][1]."n";
    break;
    }

    It's not pretty. It's not very flexible. But it's not meant to be. It's meant to dump out a bunch of data in three different formats.

    And is it fast? You bet!
    Mine:
    1.6 seconds for 1000 iterations.
    MickoZ (OO version):
    3.13 seconds for 1000 iterations.
    These numbers vary very slightly with each trial but not enough to be significant.

    Basically we can say non-OO is faster than OO. 200% faster. Kind of significant.

    Notice I

  • Ren

    Chasing the Milliseconds…

    Does a few extra milliseconds saved really mean that much?
    The solution to the problem described above should have a pretty much constant runtime, and simple enough that most can write a decent solution.

    There seems to be far too much emphasis on optimisations within PHP, which don’t really provide real benefit.

    IMO, the list of priorities in developing any software, in (rough) order of importance. (Kind of depends on what your developing.)

    1. Secure
    2. Accurate (bug free)
    3. Scalable
    4. Usable (for the user)
    5. Maintainable code
    6. Speed

    A few are opposing forces, to make an application more secure you generally lose some speed. (eg if didn’t perform any validation of external inputs, it’d be quick, but insecure as bank vault made from cardboard.)

    The key to imo to writing efficient code is recoginising PHP is a high level language, with alot of functions which should be orders of magnitude faster than anything you can write in pure PHP. So use them as often as possible.

  • saurab

    The idea of OO “versus” procedural stems from the fact that people most inclined to writing “predominantly” procedural code do so when they are developing “an” application, where as people who are inclined towards predominantly OO code are really developing reusable classes/libraries with their eyes set on “several” similar applications/projects. Hence, one will find that to build a web app most people use a nice mix of procedural and OO, where as when one is developing libraries (like for PEAR) or frameworks then OO is predominantly used … this makes sense in a way …
    But to use ONLY OO for a one-off web app is a little foolish IMO.

  • lauriek

    “Please forgive my trolling. Have a read at this timeless article: http://www.perl.com/pub/a/2000/12/advocacy.html

    Excellent link tribalist, thanks!

  • saurab

    With regard to the discussion about the merits of OOP etc .. this article is interesting :
    http://www.devx.com/opinion/Article/26776

    Disclaimer: I dont share the author’s views entirely

  • Serenarules

    Hi guys, I just thought I’d softly speak my thoughts. It seems there are several issues in question here. I see four distinct coding methods: linear, procedural, object oriented, and a balanced mixture of any of the others.

    I have never understood the tribalism associated with OOP vs everything else. PHP is, in effect, a linear language. Unlike a windows desktop app, which is persistant, a PHP script moves from “top” to “bottom”, skips around in the middle a bit, then exits, no matter what coding style you choose. To be honest, even a windows app is linear in that while the app is in “life”, a message queue is being cycled through. Once this queue is stopped, the app is terminated.

    The second issue is one of developer experience and intelligent design. This can apply to all methods of coding. I think we all agree that there are both good and bad developers, despite their style.

    The third issue is the “need” for the app. If all I’m doing is adding unrelated one-shot output scripts to an otherwise static page, I’m not about to toss out an Abstract Interface, and Implementation, and some code to use it, for each one. I’m just gonna stick in an include to a small dedicated linear script. However, if the wholw app is to be generated, and needed to be extendable, then a more oop methodology would be the way to go.

    What Harry should have done here was ask that the linear/procedural people get together and provide the best script among them, have the OOP people to do the same, and allow them to take as long as they need to tweek the code. THEN test the speed of each and declare the winner.

    As it is, from all the comments here (and I waited before commenting), it is plainly clear that the answer is NOT evident. Otherwise, nobody would’ve posted a reply in the first place.

    Eh?

  • Ghandi

    It has been almost a month with no new post. Have we lost the great Harry Fuecks?

  • Zoltar

    (written in “simple English”)

    I think you should understand where is a difference between speed of code and speed of coding.

    In the procedural aproach (or even in “in-place” aproach like in above code), you can implement something fast,
    it will be simple to write (only first time) and the performance can be better than OOP.
    You can even use ASM if you forget about PHP, but we are talking about PHP, so…
    Such a code will be a short, compact and solid code, UNMAINTABLE CODE.

    Even you as an author, after few changes, can be lost in this code (usually after holidays).

    Programming in OOP IS slower – you have to think (at least a little) about your design, leading you to a
    better, more flexible solution. The code is longer, can be too long, but for someone who knows it it will be
    very easy to correct, fix or improve it. This is because the OOP code has a build-in architecture
    (procedures do not have any architecture if you skip proc. name and parameters).

    When dealing with PHP, HTTP or SQL databases, I think you can ignore the fact that your program will be 10-100x
    slower than it’s Assembler version or maybe 1.2 slower than it’s procedural version.
    Why? Because fast-and-easy, no-thinking code will be 100x more expensive to fix/understand/optimize/maintain.

    So if you are comparing OOP and procedural programming, you should know, that if
    you are dealing with such devices like SQL or HTTP, few milliseconds more will not lead you to a major
    performance bottleneck. It’s probably more common that a bad design leads to slow solutions, not a slow methodology.

    I was working in the past with large software projects and I cannot imagine them finished on-time without OOP. But
    now I working with simple PHP scripts (MySQL, COBOL parsing) and procedural aproach is enough for me, so it realy
    depends on the project size what aproach is better. I have even implemented a database grid library
    with paging, sorting and grouping – all in about 10-20 procedures. And it works. But it will be probably work better
    in the future when converted to OOP when the number of procedures will increase.

    In my opinion not everything should be an object – some string functions or system-oriented procedures
    can work faster without OOP.

    Also, do not forget that you can “emulate” OOP in procedural programming:

    function drawObject($thisObj, $x, $y) {
    // Draw object’s caption
    $caption = $thisObj["caption"]; or $caption = $thisObj[0];
    drawCaption($caption, $x, $y);
    // Draw object’s lines
    $lines = $thisObj["lines"]; or $lines = $thisObj[1];
    drawLines($lines, $x, $y + 20);
    // Call virtual method “drawFooter”:
    $handle_draw_footer = $thisObj["drawFooter"]; or = $thisObj[3];
    $handle_draw_footer($x, $y+ 30);
    // etc…
    }