It is obvious that a resource that consumes more memory will always be more expensive.
The more code, even if it is a comma more, it consumes more memory.
Example:
Teste1
<?php
//
Teste2
<?php
//
Teste2 consumes more resources simply by having an extra line break. Of course, we’re not considering caching here.
Based on this, imagine the comparison between a function and a class. A class requires a little more memory, requires instantiation of the object, etc. A function only receives the parameters and returns the result procedural.
Also note how the environment and the way you use resources greatly influence performance. Let’s take the example of the @Allanandrade response
Datetime
for($i = 0; $i < 100000; $i++){
$tmp = DateTime::createFromFormat('U', strtotime('+3 days'))->format('Y-m-d H:i:s');
}
/*
tempo: 0.76813006401062 (segundos)
pico memória: 435824 bytes
memória final: 399816 bytes
*/
date()
for($i = 0; $i < 100000; $i++){
$tmp = date('Y-m-d H:i:s', strtotime('+3 days'));
}
/*
tempo: 0.31057095527649 (segundos)
pico memória: 435328 bytes
memória final: 399296 bytes
*/
Note that the cost of memory doesn’t even change with 1 million runs. Obviously the class has a cache engine or internal optimization. Otherwise the memory cost would be much higher.
Time is also "light years" from Allan’s response test. Since he didn’t post how he did the tests, what environment, etc., I can’t compare it to his results. It may also have confused the time of micro, Mili or seconds. If it can make it clearer, we can have a more accurate comparison.
Now we will use it in a "smart" way, because we are dealing with an object and it makes no sense to instantiate it multiple times for a single purpose. In this case we cannot blame the language, the environment or tools. It is the programmer’s fault.
Here we create the instance and set the interval outside the loop of repetition. For this is the obvious to do.
In the first test, despite the use of Datetime, is incoherently using strtotime()
. The right thing would be to use the class’s own resources.
For clarification, I will use the function date_interval_create_from_date_string() which is the procedural version of DateInterval::createFromDateString(). Actually, it’s an alias.
$date = new DateTime('2016-08-30');
$interval = date_interval_create_from_date_string('3 days');
for($i = 0; $i < 100000; $i++){
$tmp = $date->add($interval)->format('Y-m-d');
}
/*
tempo: 0.18332006645203 (segundos)
pico memória: 436384 bytes
memória final: 400856 bytes
*/
Note that now the "game turned" to a difference that we can consider "brutal". Almost half the time compared to the test using the function date()
.
To avoid being unfair, let’s optimize the procedural style
$interval = strtotime('+3 days');
for($i = 0; $i < 100000; $i++){
$tmp = date('Y-m-d H:i:s', $interval);
}
/*
tempo: 0.15265989303589 (segundos)
pico memória: 435376 bytes
memória final: 399344 bytes
*/
Point to the procedural style!!
Still, considering an unusual situation that is run 1 million times, the difference is very small. Only 0.03 microseconds.
If we apply use of optimizers such as opcache, among others, the difference can fall to zero or even change sides because the latest features have features that allow for better optimization. Old functions, usually not.
Wait! There’s more!
A little change, using something more appropriate:
$date = new DateTime('2016-08-30');
$interval = new DateInterval('P3D');
for($i = 0; $i < 100000; $i++){
$tmp = $date->add($interval);
}
/*
tempo: 0.1128888130188 (segundos)
pico memória: 435824 bytes
memória final: 400040 bytes
*/
The game turned again to Datetime class.
A difference of 0.04 seconds faster compared to the best performance in function use date()
so far.
Regarding the cost of memory, obviously it will not change, because the class has a larger amount of codes. However, it is an irrelevant cost. The most relevant thing here, within this test context, is the speed.
In a general summary, performance depends on a set of factors. Most are purely logical and common sense in the use of tools.
We may think that all of these are micro-timizations, but as we can see, depending on how it is done and summed up with other optimized routines, all together, make a significant difference.
Considerations
One has to consider the context under which conditions the X or Y resource will be used. Sometimes a simple date()
Formatting anything is more convenient. Other times you need something a little more complex where the use of procedural functions complicate. At this point comes common sense to know how to discern what is most appropriate. Keep in mind the kiss principle (Keep it simple, stupid).
Because they were written at the beginning of the creation of PHP, the old functions do not have adequate standards compared to more modern languages. For this, PHP has been gradually deploying features like the class DateTime
which is already present in the language since 2004 but, some programmers, due to the dissemination of disinformation, simply unaware or ignore. The 12-year time does not seem like much, but in the computer world is the equivalent of 1 century in human life.
IT evolves very fast, and if we get caught up in methods, customs and actions, we lose the thread and get stuck in an outdated and often ignorant conception.
I can show more examples of how to further optimize both styles above, including using optimizers and cache, but I believe the above examples and explanations have made it clear.
How the tests were performed?
An important point is, all this ran under Windows and PHP as Apache module.
Also try running a well-configured Linux environment with PHP-FPM under Nginx. Finally, test in different environments. It is well known that PHP as a module is less performative than as CGI or these new media like PHP-FPM.
Important to know that the benchmark was made using only PHP itself to simulate a real web environment to the fullest.
The memory cost may be lower considering only the execution of the proposed scripts. The end result of memory costs includes a small bootstrap and the loading of 2 simple libraries for running time and memory calculation.
The complete script:
<?php
date_default_timezone_set('Asia/Tokyo');
ini_set('error_reporting', E_ALL & ~E_STRICT & ~E_DEPRECATED); // & ~E_NOTICE
ini_set('log_errors', true);
ini_set('html_errors', false);
ini_set('display_errors', true);
define('CHARSET', 'UTF-8');
ini_set('default_charset', CHARSET);
mb_http_output(CHARSET);
mb_internal_encoding(CHARSET);
header('Content-Type: text/html; charset='.CHARSET);
include 'Bench.php';
include 'Memory.php';
use \Tipui\Libs\Bench as Bench;
use \Tipui\Libs\Memory as Memory;
Bench::Start();
// Aqui coloca o script que deseja testar.
$bench = Bench::Calc();
$memory = Memory::GetData();
echo '<pre>';
print_r($bench);
print_r($memory);
echo '</pre>';
Bench.php
<?php
namespace Tipui\Libs;
class Bench
{
protected static $ini;
public static function Start($id = 0)
{
/*
Get the start time in microseconds, as a float value
*/
self::$ini[$id] = microtime(true);
}
public static function Calc($id = 0)
{
/*
Get the difference between the start and the end time in microseconds, as a float value
*/
$end = microtime(true);
$diff = $end - self::$ini[$id];
/*
Break the difference into seconds and microseconds
*/
return array($diff - intval($diff), self::$ini[$id], $end);
}
}
Memory php.
<?php
namespace Tipui\Libs;
class Memory
{
private static $data;
public static function GetData($id = 0)
{
/*
Get the start time in microseconds, as a float value
*/
self::$data[$id]['peak'] = memory_get_peak_usage();
self::$data[$id]['current_usage'] = memory_get_usage();
return self::$data[$id];
}
public static function Usage($id = 0)
{
/*
Get the start time in microseconds, as a float value
*/
return self::$data[$id]['usage'] = memory_get_usage();
}
}
Ambience
SO: Windows 10 pro 64bit
RAM: 2 X 8GB (DDR3)
CPU: Intel i7-4770K @ 3.50GHz
PHP 7.0.5 (módulo)
Apache 2.4.20
(Hardware in default manufacturer setagens. Windows, Apache and PHP also in default settings.)
If you do not have a clear reason to worry about performance (based on a performance test for example), avoiding the object will be considered a microtimization and therefore superfluous and prone to worsening the readability of the code. If using the object brings you benefits, prefer the object.
– Piovezan
Just as if the object does not bring any benefit, do not use it :) Not even by performance, if it were the case that the object is faster, which is not.
– Maniero
@Wallacemaxters "Using object is heavier than using function" take it out of your hair, use design patterns, use code coherence, in the example cited to
classe DateTime
has numerous advantages overdate
and honestly any and every answer will not convince that one is better than the other, exhaustion test only brings conceptual damage mainly with this aspect, I guarantee if it will not instilling 10000classes Datetime
. Just a developer positioning that has been using this for a long time ...– novic