Recently I had a little discussion about our style guide with one of the co-workers. And the matter was concerning the line length. Most default is to limit the line length with 79-85 characters - because of terminals, printing etc. But an other question took my head in the middle of the conversation: limiting the line length would mean for example to encapsulate deep included blocks of the code into functions - sounds not bad, but ...
So such a strategy would inscrease the functions count in the app. But, as I knew already, the inline code must be faster as the same code, incapsulated in a function. Specifically with PHP it happens rather because the function must be found in the internal symbol table, which takes an additional time. So then, I've decided to make a little benchmark to determine, what the time difference is, if I'm using a function or not. My curiosity was so far, then I made that benchmarks not only for PHP, but for Perl and Python too.
PHP:
#!/usr/bin/env php
<?php
// How many iterations do we wanna do
$max = 1000000;
// function calls
$tm_start = array_sum(explode(' ', microtime()));
for($i = 0; $i < $max; $i++) {
do_something();
}
$secs_total = array_sum(explode(' ', microtime())) - $tm_start;
printf("Function calls time: %.3fs\n", $secs_total);
// inline
$tm_start = array_sum(explode(' ', microtime()));
for($i = 0; $i < $max; $i++) {
$a = array(1, 2, 3, 4, 5, 6, 7, 42);
if($a[0] == 1) {
if(true == false) {
}
}
}
$secs_total = array_sum(explode(' ', microtime())) - $tm_start;
printf("Inline code time: %.3fs\n", $secs_total);
function do_something()
{
$a = array(1, 2, 3, 4, 5, 6, 7, 42);
if($a[0] == 1) {
do_something_else();
}
}
function do_something_else()
{
if(true == false) {
}
}
?>
Invoking it brought:
BASH:
user@host:~/programming/php$ ./inline_bench.php
Function calls time: 3.838s
Inline code time: 2.191s
I would say, really bad - using a function maked the app up to 45% slowlier.
Hm, and what says perl?
PERL:
#!/usr/bin/env perl
use strict;
use Time::HiRes qw(gettimeofday);
# how many iterations do we wanna do
my $max = 1000000;
my ($tm_start, $secs_total, $epochseconds, $microseconds, $i);
# function calls
($epochseconds, $microseconds) = gettimeofday;
$tm_start = $epochseconds + $microseconds/10**6;
for($i = 0; $i < $max; $i++) {
&do_something();
}
($epochseconds, $microseconds) = gettimeofday;
$secs_total = $epochseconds + $microseconds/10**6 - $tm_start;
printf("Function calls time: %.3fs\n", $secs_total);
#inline
($epochseconds, $microseconds) = gettimeofday;
$tm_start = $epochseconds + $microseconds/10**6;
for($i = 0; $i < $max; $i++) {
my $a = [1, 2, 3, 4, 5, 6, 7, 42];
if($a->[0] == 1) {
if(1 == 0) {
}
}
}
($epochseconds, $microseconds) = gettimeofday;
$secs_total = $epochseconds + $microseconds/10**6 - $tm_start;
printf("Inline code time: %.3fs\n", $secs_total);
sub do_something()
{
my $a = [1, 2, 3, 4, 5, 6, 7, 42];
if($a->[0] == 1) {
do_something_else();
}
}
sub do_something_else()
{
if(1 == 0) {
}
}
BASH:
user@host:~/programming/perl$ ./inline_bench.pl
Function calls time: 2.642s
Inline code time: 2.304s
Sound much much better, doesn't it? It's not only faster as PHP itself, but using a function slows the app only for 15%.
The next:
PYTHON:
#!/usr/bin/env python
import time
def do_something():
a = [1, 2, 3, 4, 5, 6, 7, 42];
if a[0] == 1:
do_something_else()
def do_something_else():
if 1 == 0:
pass
# how many iterations do we wanna do
max = 1000000
# function calls
tm_start = time.time()
for i in range(max):
do_something()
secs_total = time.time() - tm_start;
print "Function calls time: %(total).3fs" % {"total" : secs_total}
# inline code
tm_start = time.time()
for i in range(max):
a = [1, 2, 3, 4, 5, 6, 7, 42];
if a[0] == 1:
if 1 == 0:
pass
secs_total = time.time() - tm_start;
print "Inline code time: %(total).3fs" % {"total" : secs_total}
BASH:
user@host:~/programming/python$ ./inline_bench.py
Function calls time: 1.606s
Inline code time: 1.044s
As we see, this one is the fastest. But using a function makes the code 35% slowlier (note that making it as module to get the bytecode brought nothing).
So it was very interesting expierience for me. Next time I write something, I'll be aware )).
Seriously, hm .. may be one shoud think about a mechanism to make define functions as inline (such in c) possible. Another thing - is how to make the code good structured but no to be traped from that "I'll make a function from this".
Useful links:
http://paul-m-jones.com/?p=276
http://www.parashift.com/c++-faq-lite/inline-functions.html