Skip to content

Instantly share code, notes, and snippets.

@nikic
Created June 22, 2012 23:42
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save nikic/2975796 to your computer and use it in GitHub Desktop.
Save nikic/2975796 to your computer and use it in GitHub Desktop.
Microbenchmark of generator implementation
<?php
error_reporting(E_ALL);
function xrange($start, $end, $step = 1) {
for ($i = $start; $i < $end; $i += $step) {
yield $i;
}
}
class RangeIterator implements Iterator {
protected $start;
protected $end;
protected $step;
protected $key;
protected $value;
public function __construct($start, $end, $step = 1) {
$this->start = $start;
$this->end = $end;
$this->step = $step;
}
public function rewind() {
$this->key = 0;
$this->value = $this->start;
}
public function valid() {
return $this->value < $this->end;
}
public function next() {
$this->value += $this->step;
$this->key += 1;
}
public function current() {
return $this->value;
}
public function key() {
return $this->key;
}
}
function urange($start, $end, $step = 1) {
$result = [];
for ($i = $start; $i < $end; $i += $step) {
$result[] = $i;
}
return $result;
}
function testTraversable($name, callable $traversableFactory) {
$startTime = microtime(true);
foreach ($traversableFactory() as $value) {
// noop
}
echo $name, ' took ', microtime(true) - $startTime, ' seconds.', "\n";
}
function testVariants($count) {
testTraversable(
"xrange ($count)",
function() use($count) { return xrange(0, $count); }
);
testTraversable(
"RangeIterator ($count)",
function() use($count) { return new RangeIterator(0, $count); }
);
testTraversable(
"urange ($count)",
function() use($count) { return urange(0, $count); }
);
testTraversable(
"range ($count)",
function() use($count) { return range(0, $count); }
);
}
testVariants(1000000);
testVariants(10000);
testVariants(100);
xrange (1000000) took 0.14633202552795 seconds.
RangeIterator (1000000) took 0.5944938659668 seconds.
urange (1000000) took 0.28175210952759 seconds.
range (1000000) took 0.23163318634033 seconds.
xrange (10000) took 0.0015981197357178 seconds.
RangeIterator (10000) took 0.0065171718597412 seconds.
urange (10000) took 0.0028119087219238 seconds.
range (10000) took 0.0022850036621094 seconds.
xrange (100) took 7.8916549682617E-5 seconds.
RangeIterator (100) took 0.00010895729064941 seconds.
urange (100) took 5.5074691772461E-5 seconds.
range (100) took 8.082389831543E-5 seconds.
xrange (1000000) took 0.14681696891785 seconds.
RangeIterator (1000000) took 0.60637879371643 seconds.
urange (1000000) took 0.29368591308594 seconds.
range (1000000) took 0.22470617294312 seconds.
xrange (10000) took 0.0014379024505615 seconds.
RangeIterator (10000) took 0.0056979656219482 seconds.
urange (10000) took 0.002910852432251 seconds.
range (10000) took 0.0023188591003418 seconds.
xrange (100) took 5.1021575927734E-5 seconds.
RangeIterator (100) took 0.00014209747314453 seconds.
urange (100) took 5.4121017456055E-5 seconds.
range (100) took 4.3869018554688E-5 seconds.
xrange (1000000) took 0.14807891845703 seconds.
RangeIterator (1000000) took 0.60018301010132 seconds.
urange (1000000) took 0.28284788131714 seconds.
range (1000000) took 0.22018909454346 seconds.
xrange (10000) took 0.0013790130615234 seconds.
RangeIterator (10000) took 0.006242036819458 seconds.
urange (10000) took 0.0016648769378662 seconds.
range (10000) took 0.0019738674163818 seconds.
xrange (100) took 9.2029571533203E-5 seconds.
RangeIterator (100) took 0.00013899803161621 seconds.
urange (100) took 5.1975250244141E-5 seconds.
range (100) took 4.3153762817383E-5 seconds.
@dkarvounaris
Copy link

dkarvounaris commented Apr 24, 2016

Just for comparison, the same benchmark on the same system, but with PHP 5.6.19 instead 7.0:

xrange        (1000000) took 0.84735608100891 seconds.
RangeIterator (1000000) took 2.6602609157562 seconds.
urange        (1000000) took 0.60670304298401 seconds.
range         (1000000) took 0.34244179725647 seconds.
xrange        (10000) took 0.010324001312256 seconds.
RangeIterator (10000) took 0.027228832244873 seconds.
urange        (10000) took 0.0047950744628906 seconds.
range         (10000) took 0.0020461082458496 seconds.
xrange        (100) took 0.00014185905456543 seconds.
RangeIterator (100) took 0.00033211708068848 seconds.
urange        (100) took 8.6069107055664E-5 seconds.
range         (100) took 7.1048736572266E-5 seconds.
xrange        (10000000) took 8.7790288925171 seconds.
RangeIterator (10000000) took 26.90533208847 seconds.
urange        (10000000) took 6.6500968933105 seconds.
range         (10000000) took 3.7362380027771 seconds.

One can say by these numbers, if you want to make sure, your code is on PHP7 as slow as on PHP5, then make sure you use Iterator, which is performing equally bad on both versions!

@time0x
Copy link

time0x commented Mar 20, 2017

mac 2015 php7

xrange        (1000000) took 0.049606084823608 seconds.
RangeIterator (1000000) took 0.30497097969055 seconds.
urange        (1000000) took 0.065662145614624 seconds.
range         (1000000) took 0.026712894439697 seconds.
xrange        (10000) took 0.00052690505981445 seconds.
RangeIterator (10000) took 0.0027179718017578 seconds.
urange        (10000) took 0.00044798851013184 seconds.
range         (10000) took 0.00019502639770508 seconds.
xrange        (100) took 6.9141387939453E-6 seconds.
RangeIterator (100) took 4.0054321289062E-5 seconds.
urange        (100) took 6.9141387939453E-6 seconds.
range         (100) took 2.8610229492188E-6 seconds.

@octisfall
Copy link

mac mini 2018, i7, php 8, docker for mac

xrange        (1000000) took 0.53661203384399 seconds.
RangeIterator (1000000) took 1.2678070068359 seconds.
urange        (1000000) took 0.28700590133667 seconds.
range         (1000000) took 0.066593170166016 seconds.
xrange        (10000) took 0.005033016204834 seconds.
RangeIterator (10000) took 0.012601137161255 seconds.
urange        (10000) took 0.0026609897613525 seconds.
range         (10000) took 0.00066709518432617 seconds.
xrange        (100) took 0.00012302398681641 seconds.
RangeIterator (100) took 0.00025606155395508 seconds.
urange        (100) took 3.814697265625E-5 seconds.
range         (100) took 3.6001205444336E-5 seconds.

@AntonMuxa
Copy link

hp 850 g6 i7 docker php 8.1
xrange (1000000) took 0.2816960811615 seconds.
RangeIterator (1000000) took 0.8405749797821 seconds.
urange (1000000) took 0.11258292198181 seconds.
range (1000000) took 0.026424169540405 seconds.
xrange (10000) took 0.0025100708007812 seconds.
RangeIterator (10000) took 0.009044885635376 seconds.
urange (10000) took 0.00084590911865234 seconds.
range (10000) took 0.00028705596923828 seconds.
xrange (100) took 3.2186508178711E-5 seconds.
RangeIterator (100) took 9.1075897216797E-5 seconds.
urange (100) took 7.8678131103516E-6 seconds.
range (100) took 1.9073486328125E-6 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment