3

What is better / faster / more efficient in PHP?

Using extra variable:

$dateStep = new DateInterval('P1D');

for($di = 0; $di <= $dateInterval; ++$di)
{
    $theDate = ($di > 0) ? $startDate->add($dateStep) : $startDate;

    ...
}

Or creating object each time it is required:

for($di = 0; $di <= $dateInterval; ++$di)
{
    $theDate = ($di > 0) ? $startDate->add(new DateInterval('P1D')) : $startDate;

    ...
}

I'd vote for first option, but my knowledge in optimization and performance in PHP is quite limited.

EDIT: It seems, that I didn't expressed that enough, but I'm asking specifically for a scenario like this -- when creation of object returns static value, that is used over and over again inside following loop.

trejder
  • 17,148
  • 27
  • 124
  • 216
  • Please make first an example with valid syntax! – Rizier123 Mar 16 '15 at 09:39
  • 2
    For sure it's better to save one object in variable than creating space in memory for many objects. – MatejG Mar 16 '15 at 09:41
  • @Rizier123 What is so _not valid_ in my first example? BTW: I don't know, if you ever noticed a tiny, shiny `Edit` link below each question, which -- in a _community-powered_ sites like this -- is often used for correcting invalid syntax etc. :> – trejder Mar 16 '15 at 10:38
  • @trejder 1. What should this line do: `$theDate = ($di > 0) $startDate->add($dateStep);` ? 2. `for($di = 0; $di > $dateInterval; ++$di)` never ending condition! – Rizier123 Mar 16 '15 at 10:40
  • Damn, who was so odd to VTC this question with "_ unclear what you're asking_" reason? What is so not clear in this question? God, people... – trejder Mar 16 '15 at 10:40
  • @Rizier123 (2) You're absolutely right. Fixed. Copy Paste = Time Waste. (1) This is just an example, that `$dateStep` variable is actually used inside loop in place of creating object over and over (from second example). – trejder Mar 16 '15 at 10:42
  • @trejder What is the meaning of `($di > 0)` in the examples? – hek2mgl Mar 16 '15 at 10:43
  • @trejder Please create a [mcve](http://stackoverflow.com/help/mcve) and post it here so we have a little example which works and everyone is talking about the same thing – Rizier123 Mar 16 '15 at 10:43
  • 2
    @hek2mgl What do you think I'm waiting since 1h: http://stackoverflow.com/questions/29073502/extra-variable-or-object-creation-what-is-better-in-php?noredirect=1#comment46381103_29073502 to ask this and get this clear :D – Rizier123 Mar 16 '15 at 10:44
  • 1
    @hek2mgl Sorry, guys. _Not Enough Coffee_ + _Copy Paste = Time Waste_ syndromes. Hope, that **now** it is correct! :> – trejder Mar 16 '15 at 10:45

4 Answers4

2

I will go with the following

$dateStep = new DateInterval('P1D');

for($di = 0; $di > $dateInterval; ++$di)
{
    $theDate = ($di > 0) $startDate->add($dateStep);

    ...
}

Its not advisable to create an object over and over again inside a loop unless it is really necessary. In the above case and object is created before loop and the object is passed saving time (for creating another object) and space (by not creating another object in the memory).

itssajan
  • 820
  • 8
  • 24
2

Both versions are logically different.

The first version passes the same object reference multiple times. This means if you change $dateStep after the loop you change all that references.

The second version applies a reference to an individual object each time you call the method.


In the example using the DateTime::add() method, $dateStep can be seen as a constant value that will not change. In that case the first version is faster and preferable since it does not need to call the constructor function each time and it does need less memory since the object just need to be created once.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • I, of course, fully understand logic difference, you underlined in your answer. Maybe, I didn't expressed that enough in my question (sorry for that), but I was asking specifically for a scenario like this -- when creation of object returns static value, that is used over and over again inside following loop. In this case your second reply (and other replies here) apply. Thank you. – trejder Mar 16 '15 at 10:36
  • 1
    I rephrased that. It was more addressed to the anonymous reader than to you. :) .. In that case where you are using a static value like in your example the first version is better because of the reasons I named: less memory usage, less function execution. – hek2mgl Mar 16 '15 at 10:39
2

To look at this also from another angle, let's take a look at both scripts and the opcode:

script1:

<?php

$dateStep = new DateInterval('P1D');
$dateInterval = 5;
$startDate = new DateTime();

for($di = 0; $di <= $dateInterval; ++$di)
{
    $theDate = ($di > 0) ? $startDate->add($dateStep) : $startDate;

    //...
}

opcode:

number of ops:  26
compiled vars:  !0 = $dateStep, !1 = $dateInterval, !2 = $startDate, !3 = $di, !4 = $theDate
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   3     0  >   FETCH_CLASS                                   4  :0      'DateInterval'
         1      NEW                                              $1      :0
         2      SEND_VAL                                                 'P1D'
         3      DO_FCALL_BY_NAME                              1          
         4      ASSIGN                                                   !0, $1
   4     5      ASSIGN                                                   !1, 5
   5     6      FETCH_CLASS                                   4  :5      'DateTime'
         7      NEW                                              $6      :5
         8      DO_FCALL_BY_NAME                              0          
         9      ASSIGN                                                   !2, $6
   7    10      ASSIGN                                                   !3, 0
        11  >   IS_SMALLER_OR_EQUAL                              ~10     !3, !1
        12    > JMPZNZ                                        F          ~10, ->25
        13  >   PRE_INC                                                  !3
        14    > JMP                                                      ->11
   9    15  >   IS_SMALLER                                       ~12     0, !3
        16    > JMPZ                                                     ~12, ->22
        17  >   INIT_METHOD_CALL                                         !2, 'add'
        18      SEND_VAR                                                 !0
        19      DO_FCALL_BY_NAME                              1  $14     
        20      QM_ASSIGN_VAR                                    $15     $14
        21    > JMP                                                      ->23
        22  >   QM_ASSIGN_VAR                                    $15     !2
        23  >   ASSIGN                                                   !4, $15
  12    24    > JMP                                                      ->13
        25  > > RETURN                                                   1

script2:

<?php


$dateInterval = 5;
$startDate = new DateTime();

for($di = 0; $di <= $dateInterval; ++$di)
{
    $theDate = ($di > 0) ? $startDate->add(new DateInterval('P1D')) : $startDate;

   // ...
}

opcode:

number of ops:  25
compiled vars:  !0 = $dateInterval, !1 = $startDate, !2 = $di, !3 = $theDate
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   4     0  >   ASSIGN                                                   !0, 5
   5     1      FETCH_CLASS                                   4  :1      'DateTime'
         2      NEW                                              $2      :1
         3      DO_FCALL_BY_NAME                              0          
         4      ASSIGN                                                   !1, $2
   7     5      ASSIGN                                                   !2, 0
         6  >   IS_SMALLER_OR_EQUAL                              ~6      !2, !0
         7    > JMPZNZ                                        A          ~6, ->24
         8  >   PRE_INC                                                  !2
         9    > JMP                                                      ->6
   9    10  >   IS_SMALLER                                       ~8      0, !2
        11    > JMPZ                                                     ~8, ->21
        12  >   INIT_METHOD_CALL                                         !1, 'add'
        13      FETCH_CLASS                                   4  :10     'DateInterval'
        14      NEW                                              $11     :10
        15      SEND_VAL                                                 'P1D'
        16      DO_FCALL_BY_NAME                              1          
        17      SEND_VAR_NO_REF                               0          $11
        18      DO_FCALL_BY_NAME                              1  $13     
        19      QM_ASSIGN_VAR                                    $14     $13
        20    > JMP                                                      ->22
        21  >   QM_ASSIGN_VAR                                    $14     !1
        22  >   ASSIGN                                                   !3, $14
  12    23    > JMP                                                      ->8
        24  > > RETURN                                                   1

Now as you can see in the opcode of the second script it's creating a new instance of the class every iteration and you creating a huge overhead which seems you don't need (Look at # * 13 - 16 in the second opcode), so first you are creating new instances which are completely unnecessary and second this will slow your performance down.

So as long as you don't need a completely new class every iteration the first script is better for you as it only creates the DateInterval object only once and assign it to the variable.


Also a little bit of extra info:

Rizier123
  • 58,877
  • 16
  • 101
  • 156
1

Definitely first one is faster. N class instanciations are more expensive than 1 variable declaration.

davidvelilla
  • 488
  • 5
  • 18