H3XED

PHP Class vs Object vs Array Attribute Performance

Apr 17, 2013   Programming   Nick Vogt   Comments
Please note that this post is over a year old and may contain outdated information.
PHPRecently I was curious about the performance (in terms of access and assignment time) between class static attributes, object attributes, and array elements. Say if you're wanting to store some information that is accessed regularly, and want to know which method is the fastest.

The test is one milllion iterations of accessing each type and was performed on PHP versions 5.2.17 and 5.3.5. The overhead of the loop was taken into account for each performance time and the tests were repeated to find an average.


Results


// Class static attribute
class test1
{
   public static $data = 'Hello world!';
}
for($i = 0; $i < 1000000; $i ++) $test = test1::$data;
// Result: 180 milliseconds


// Object attribute
class test2
{
   public $data = 'Hello world!';
}
$test2 = new test2();
for($i = 0; $i < 1000000; $i ++) $test = $test2->data;
// Result: 115 milliseconds


// Array element
$test3 = array(
   'data' => 'Hello world!'
);
for($i = 0; $i < 1000000; $i ++) $test = $test3['data'];
// Result: 78 milliseconds


Accessing and assigning data from an array is the fastest. I also performed the same test with integers, and no assignment at all, with similar results.


Full Test Script


In case you're curious, the entire script I used to perform this test is:

<?php

// Reset
if(isset($_GET['reset']))
{
   session_start();
   session_destroy();
   header('Location: performance.php');
   exit;
}


// Function averages all numbers in array
function array_average($a)
{
   $sum = 0.0;
   foreach($a as $v) $sum+= $v;
   return round($sum / count($a));
}


// Start session to store averages
session_start();
if(!isset($_SESSION['overhead'])) $_SESSION['overhead'] = array();
if(!isset($_SESSION['test1'])) $_SESSION['test1'] = array();
if(!isset($_SESSION['test2'])) $_SESSION['test2'] = array();
if(!isset($_SESSION['test3'])) $_SESSION['test3'] = array();


// Test variable for assignment performance
$test = '';


// Class static attribute
class test1
{
   public static $data = 'Hello world!';
}

// Object attribute
class test2
{
   public $data = 'Hello world!';
}
$test2 = new test2();

// Array element
$test3 = array(
   'data' => 'Hello world!'
);


// Get loop overhead
$start = microtime(true) * 1000;
for($i = 0; $i < 1000000; $i ++) {}
$_SESSION['overhead'][] = microtime(true) * 1000 - $start;


// Test 1
$start = microtime(true) * 1000;
for($i = 0; $i < 1000000; $i ++) $test = test1::$data;
$_SESSION['test1'][] = microtime(true) * 1000 - $start;

// Test 2
$start = microtime(true) * 1000;
for($i = 0; $i < 1000000; $i ++) $test = $test2->data;
$_SESSION['test2'][] = microtime(true) * 1000 - $start;

// Test 3
$start = microtime(true) * 1000;
for($i = 0; $i < 1000000; $i ++) $test = $test3['data'];
$_SESSION['test3'][] = microtime(true) * 1000 - $start;


// Show results (each refresh increases accuracy average)
$avg_overhead = array_average($_SESSION['overhead']);
$avg_test1 = array_average($_SESSION['test1']);
$avg_test2 = array_average($_SESSION['test2']);
$avg_test3 = array_average($_SESSION['test3']);
echo 'Loop overhead: '.$avg_overhead.' ms<br>';
echo 'Class attribute: '.$avg_test1.' ms ('.($avg_test1 - $avg_overhead).' ms without overhead)<br>';
echo 'Object attribute: '.$avg_test2.' ms ('.($avg_test2 - $avg_overhead).' ms without overhead)<br>';
echo 'Array element: '.$avg_test3.' ms ('.($avg_test3 - $avg_overhead).' ms without overhead)<br>';
echo 'Average over '.count($_SESSION['overhead']).' cycles.<br>';
echo 'PHP Version: '.phpversion().'<br>';
echo '<a href="performance.php?reset=true">Reset</a>';
Share This Post
Twitter

Comments (0)

Share This Post
Twitter
H3XED © Nick Vogt   RSS   Policies   Twitter