Tuesday, 29 November 2016

Perl, Python, Ruby, PHP, C, C++, Lua, tcl, javascript and Java benchmark/comparison.

Only core language functionality has been used for testing.

Originally I wanted to compare only mainstream cross platform interpreting languages - namely PHP, Perl5, Python, Ruby and Java (Sun's and OpenJDK). Then curiosity made me include C, C++, Javascript ("spidermonkey", Mozilla), Javascript ("V8", Webkit), tcl, Lua and Java GCJ.

Whilst it is interesting to compare languages to each other, Javascripts, tcl and Lua are falling outside of scope so I will not compare their features.
Technically C and C++ should not belong here because they are very different from interpreting languages by nature, however their results are important to match against.

Defaults has been used for all languages but PHP. By default PHP restrict maximum memory usage and maximum execution time. In order to complete test those parameters had to be changed in PHP runtime configuration.

Compilation time needed for C, C++ and Java wasn't counted in this testing.

This comparison consists of three parts:
Part 1: Speed.
Part 2: Memory usage.
Part 3: Language features.

Speed

Execution speed is obviously important to understand the language. I would say that if you're not considering performance at all you simply don't care about your application. However performance alone is not the most important characteristic and therefore other aspects should be taken into consideration as well.



Speed tests fall into 4 categories:
Slowest: Java gcj (native executable)
Slow: Java (openJDK); Java (Sun); Lua
Not-so-fast: tcl; Javascript (spidermonkey)
Fastest: Python; Ruby; PHP; C++; Javascript V8; C; Perl5

Memory usage


During testing memory usage were captured as per every completed step.



Result fall into five categories:
Highest: Java OpenJDK, Java Sun
High:Java GCJ
Medium:Javascript V8, Javascript sm., PHP
Low:tcl, Lua, Ruby
Lowest: Python, Perl5, C++, C

Source codes and test results


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(){

setbuf(stdout,NULL); //disable output buffering

char *str=malloc(8);
strcpy(str,"abcdefgh");

str=realloc(str,strlen(str)+8);
strcat(str,"efghefgh");     //sprintf(str,"%s%s",str,"efghefgh");

int imax=1024/strlen(str)*1024*4;

printf("%s","exec.tm.sec\tstr.length\n"); //fflush(stdout);

time_t starttime=time(NULL);
char *gstr=malloc(0);
int i=0;
char *pos;
int lngth;

char *pos_c=gstr;
int str_len=strlen(str);

    while(i++ < imax+1000){
        lngth=strlen(str)*i;
        gstr=realloc(gstr,lngth+str_len);
        strcat(gstr,str);    //sprintf(gstr,"%s%s",gstr,str);
        pos_c+=str_len;

        pos=gstr;
        while(pos=strstr(pos,"efgh")){
            memcpy(pos,"____",4);
        }

        if(lngth % (1024*256)==0){
            printf("%dsec\t\t%dkb\n",time(NULL)-starttime,lngth/1024); //fflush(stdout);
        }
    }
//printf("%s\n",gstr);

}


#include <iostream>
#include <string>
#include <time.h>

using namespace std;

main ()
{
  string str = "abcdefgh";
    str += "efghefgh";
  int imax = 1024 /str.length() * 1024 *4;
  time_t currentTime = time(NULL);
  cout << "exec.tm.sec\tstr.length" << endl;

  string find= "efgh";
  string replace ="____";
  string gstr;
  int i=0;
  int length;
//  int end=0; //  size_t end=0;

  while(i++ < imax +1000){
    gstr += str;
    gstr = gstr;
    size_t start, sizeSearch=find.size(), end=0;

    while((start=gstr.find(find,end))!=string::npos){
        end=start+sizeSearch;
        gstr.replace(start,sizeSearch,replace);
    }
    length = str.length()*i;
    if((length%(1024 * 256))==0){
        cout << time(NULL) - currentTime << "sec\t\t" << length/1024 << "kb" <<  endl;
    }
  }
// cout << gstr << endl;

return 0;
}
#!/usr/local/bin/js

var str = "abcdefgh"+"efghefgh";
var imax = 1024 / str.length * 1024 * 4;

var time = new Date();
print("exec.tm.sec\tstr.length");

var gstr = "";
var i=0;
var lngth;

while (i++ < imax+1000) {
    gstr += str;
    gstr = gstr.replace(/efgh/g, "____");
        lngth=str.length*i;
        if ((lngth % (1024*256)) == 0) {
                var curdate=new Date();
                print(parseInt(((curdate.getTime()-time.getTime())/1000))+"sec\t\t"+lngth/1024+"kb");
        }
}

public class java_test {

    public static final void main(String[] args) throws Exception {
        String str = "abcdefgh"+"efghefgh";
        int imax = 1024 / str.length() * 1024 * 4;

        long time = System.currentTimeMillis();
        System.out.println("exec.tm.sec\tstr.length\tallocated memory:free memory:memory used");
        Runtime runtime = Runtime.getRuntime();
        System.out.println("0\t\t0\t\t"+runtime.totalMemory()/1024 +":"+ runtime.freeMemory()/1024+":"+(runtime.totalMemory()-runtime.freeMemory())/1024);

        String gstr = "";
        int i=0;
        int lngth;

        while (i++ < imax+1000) {
            gstr += str;
            gstr = gstr.replaceAll("efgh", "____");
            lngth=str.length()*i;
                if ((lngth % (1024*256)) == 0) {
                        System.out.println(((System.currentTimeMillis()-time)/1000)+"sec\t\t"+lngth/1024+"kb\t\t"+runtime.totalMemory()/1024+":"+runtime.freeMemory()/1024+":"+(runtime.totalMemory()-runtime.freeMemory())/1024);
                }
        }
    }
}
#!/usr/bin/perl
$|=1;    #disable output buffering, this is necessary for proper output through pipe

my $str='abcdefgh'.'efghefgh';
my $imax=1024/length($str)*1024*4;               # 4mb

my $starttime=time();
print "exec.tm.sec\tstr.length\n";

my $gstr='';
my $i=0;

while($i++ < $imax+1000){   #adding 1000 iterations to delay exit. This will allow to capture memory usage on last step

        $gstr.=$str;
        $gstr=~s/efgh/____/g;
        my $lngth=length($str)*$i;   ##     my $lngth=length($gstr);        # Perhaps that would be a slower way
        print time()-$starttime,"sec\t\t",$lngth/1024,"kb\n" unless $lngth % (1024*256); #print out every 256kb
}

<?php


$str="abcdefgh"."efghefgh";
$imax=1024/strlen($str)*1024*4;      # 4mb

$starttime=time();
print("exec.tm.sec\tstr.length\n");

$gstr='';
$i=0;

while($i++ < $imax+1000){

        $gstr.=$str;
        $gstr=preg_replace('/efgh/','____',$gstr);
        $lngth=strlen($str)*$i;
        if($lngth % (1024*256)==0){
                print (time()-$starttime."sec\t\t".($lngth/1024)."kb\n");
        }
}

?>

#!/usr/bin/python -u
import re
import time
import sys

str='abcdefgh'+'efghefgh'
imax=1024/len(str)*1024*4   # 4mb

starttime=time.time();
print "exec.tm.sec\tstr.length"
sys.stdout.flush()

gstr=''
i=0

while (i < imax+1000):
        i=i+1
        gstr+=str
        gstr=re.sub('efgh','____',gstr)
        lngth=len(str)*i
        if(lngth % (1024*256) == 0):
                print int(time.time()-starttime),"sec\t\t",(lngth/1024),"kb"
                sys.stdout.flush()
#!/usr/bin/python3 -u
import re
import time
import sys

str='abcdefgh'+'efghefgh'
imax=1024/len(str)*1024*4   # 4mb

starttime=time.time();
print "exec.tm.sec\tstr.length"
sys.stdout.flush()

gstr=''
i=0

while (i < imax+1000):
        i=i+1
        gstr+=str
        gstr=re.sub('efgh','____',gstr)
        lngth=len(str)*i
        if(lngth % (1024*256) == 0):
                print int(time.time()-starttime),"sec\t\t",(lngth/1024),"kb"
                sys.stdout.flush()
#!/usr/bin/ruby
$stdout.sync=true;

str='abcdefgh'+'efghefgh';
imax=1024/str.length*1024*4;       # 4mb

starttime=Time.new;
print("exec.tm.sec\tstr.length\n");

gstr='';
i=0;

while i < imax+1000
        i=i+1;
        gstr+=str;
        gstr=gstr.gsub(/efgh/, "____")

        lngth=str.length*i;
        if(lngth % (1024*256)==0)
                print(((Time.new-starttime).ceil).to_s+"sec\t\t",(lngth/1024).to_s,"kb\n");
        end
end

#puts gstr;
#!/usr/bin/lua

io.stdout:setvbuf "no";             --  io.flush();

str='abcdefgh'..'efghefgh';
imax=1024/string.len(str)*1024*4;         -- 4mb

starttime=os.time();
print "exec.tm.sec\tstr.length";

gstr='';
i=0;

while i < imax+1000 do
        i=i+1;
        gstr=gstr..str;
        gstr=string.gsub(gstr,"efgh","____");
        lngth=string.len(str)*i;
        if(math.mod(lngth,1024*256)==0) then
                print(os.time()-starttime.."sec\t\t"..(lngth/1024).."kb");
        end
end



#!/usr/bin/tclsh

set str "abcdefgh"
append str "efghefgh"

set imax [expr {1024/[string length $str]*1024*4}]

set starttime [clock clicks -milliseconds]
puts "exec.tm.sec\tstr.length";

set gstr ""
set i 0

while {$i<[expr {$imax+1000}]} {
        incr i
        append gstr $str;
        regsub -all {efgh} $gstr ____ gstr
        set lngth [expr {[string length $str]*$i}]
        if {[expr {$lngth % (1024*256)}] == 0} {
                puts "[expr int([expr [clock clicks -milliseconds] - $starttime] / 1000)]sec\t\t[expr {$lngth/1024}]kb"
        }
}

exit

No comments:

Post a Comment