Skip to content

Instantly share code, notes, and snippets.

@dstogov
Created February 27, 2015 19:14
Show Gist options
  • Save dstogov/12323ad13d3240aee8f1 to your computer and use it in GitHub Desktop.
Save dstogov/12323ad13d3240aee8f1 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <sys/time.h>
#define BAILOUT 16
#define MAX_ITERATIONS 1000
int mandelbrot(double x, double y)
{
double cr = y - 0.5;
double ci = x;
double zi = 0.0;
double zr = 0.0;
int i = 0;
while(1) {
i ++;
double temp = zr * zi;
double zr2 = zr * zr;
double zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT)
return i;
if (i > MAX_ITERATIONS)
return 0;
}
}
int main (int argc, const char * argv[]) {
struct timeval aTv;
gettimeofday(&aTv, NULL);
long init_time = aTv.tv_sec;
long init_usec = aTv.tv_usec;
int x,y;
for (y = -39; y < 39; y++) {
printf("\n");
for (x = -39; x < 39; x++) {
int i = mandelbrot(x/40.0, y/40.0);
if (i==0)
printf("*");
else
printf(" ");
}
}
printf ("\n");
gettimeofday(&aTv,NULL);
double query_time = (aTv.tv_sec - init_time) + (double)(aTv.tv_usec - init_usec)/1000000.0;
printf ("C Elapsed %0.3f\n", query_time);
return 0;
}
-- By Erik Wrenholt
local BAILOUT = 16
local MAX_ITERATIONS = 1000
function iterate(x,y)
local cr = y-0.5
local ci = x
local zi = 0.0
local zr = 0.0
local i = 0
while 1 do
i = i+1
local temp = zr * zi
local zr2 = zr*zr
local zi2 = zi*zi
zr = zr2-zi2+cr
zi = temp+temp+ci
if (zi2+zr2 > BAILOUT) then
return i
end
if (i > MAX_ITERATIONS) then
return 0
end
end
end
function mandelbrot()
local t = os.time()
for y = -39, 38 do
for x = -39, 38 do
if (iterate(x/40.0, y/40) == 0) then
io.write("*")
else
io.write(" ")
end
end
io.write("\n")
end
io.write(string.format("Time Elapsed %d\n", os.time() - t))
end
mandelbrot()
<?php
define("BAILOUT",16);
define("MAX_ITERATIONS",1000);
class Mandelbrot
{
function Mandelbrot()
{
$d1 = microtime(1);
for ($y = -39; $y < 39; $y++) {
for ($x = -39; $x < 39; $x++) {
if ($this->iterate($x/40.0,$y/40.0) == 0)
echo("*");
else
echo(" ");
}
echo("\n");
}
$d2 = microtime(1);
$diff = $d2 - $d1;
printf("\nPHP Elapsed %0.3f\n", $diff);
}
function iterate($x,$y)
{
$cr = $y-0.5;
$ci = $x;
$zr = 0.0;
$zi = 0.0;
$i = 0;
while (true) {
$i++;
$temp = $zr * $zi;
$zr2 = $zr * $zr;
$zi2 = $zi * $zi;
$zr = $zr2 - $zi2 + $cr;
$zi = $temp + $temp + $ci;
if ($zi2 + $zr2 > BAILOUT)
return $i;
if ($i > MAX_ITERATIONS)
return 0;
}
}
}
ob_start();
$m = new Mandelbrot();
ob_end_flush();
?>
$BAILOUT=16;
$MAX_ITERATIONS=1000;
$begin = time();
sub mandelbrot {
local $x = $_[0];
local $y = $_[1];
local $cr = $y - 0.5;
local $ci = $x;
local $zi = 0.0;
local $zr = 0.0;
local $i = 0;
while (1)
{
$i = $i + 1;
local $temp = $zr * $zi;
local $zr2 = $zr * $zr;
local $zi2 = $zi * $zi;
$zr = $zr2 - $zi2 + $cr;
$zi = $temp + $temp + $ci;
if ($zi2 + $zr2 > $BAILOUT)
{
return $i;
}
if ($i > $MAX_ITERATIONS)
{
return 0;
}
}
}
for ($y = -39; $y < 39; $y++)
{
print("\n");
for ($x = -39; $x < 39; $x++)
{
$i = mandelbrot($x/40.0, $y/40.0);
if ($i == 0)
{
print("*");
}
else
{
print(" ");
}
}
}
print("\n");
$end = time() - $begin;
print "Perl Elapsed $end\n";
import sys, time
stdout = sys.stdout
BAILOUT = 16
MAX_ITERATIONS = 1000
class Iterator:
def __init__(self):
print 'Rendering...'
for y in range(-39, 39):
stdout.write('\n')
for x in range(-39, 39):
i = self.mandelbrot(x/40.0, y/40.0)
if i == 0:
stdout.write('*')
else:
stdout.write(' ')
def mandelbrot(self, x, y):
cr = y - 0.5
ci = x
zi = 0.0
zr = 0.0
i = 0
while True:
i += 1
temp = zr * zi
zr2 = zr * zr
zi2 = zi * zi
zr = zr2 - zi2 + cr
zi = temp + temp + ci
if zi2 + zr2 > BAILOUT:
return i
if i > MAX_ITERATIONS:
return 0
t = time.time()
Iterator()
print '\nPython Elapsed %.02f' % (time.time() - t)
BAILOUT = 16
MAX_ITERATIONS = 1000
class Mandelbrot
def initialize
puts "Rendering"
for y in -39...39 do
puts
for x in -39...39 do
i = iterate(x/40.0,y/40.0)
if (i == 0)
print "*"
else
print " "
end
end
end
end
def iterate(x,y)
cr = y-0.5
ci = x
zi = 0.0
zr = 0.0
i = 0
while(1)
i += 1
temp = zr * zi
zr2 = zr * zr
zi2 = zi * zi
zr = zr2 - zi2 + cr
zi = temp + temp + ci
return i if (zi2 + zr2 > BAILOUT)
return 0 if (i > MAX_ITERATIONS)
end
end
end
time = Time.now
Mandelbrot.new
puts
puts "Ruby Elapsed %f" % (Time.now - time)
function mandelbrot(x, y) {
local cr = y - 0.5;
local ci = x;
local zi = 0.0;
local zr = 0.0;
local i = 0;
local BAILOUT = 16;
local MAX_ITERATIONS = 1000;
while(1) {
i++;
local temp = zr * zi;
local zr2 = zr * zr;
local zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT) {
return i;
}
if (i > MAX_ITERATIONS) {
return 0;
}
}
}
function mandelbrot_run() {
local x;
local y;
// local date = Date();
for (y = -39; y < 39; y++) {
for (x = -39; x < 39; x++) {
if (mandelbrot(x/40.0, y/40.0) == 0) {
print("*");
} else {
print(" ");
}
}
print("\n");
}
// local date2 = Date();
// output += "\nJavaScript Elapsed " + (date2.getTime() - date.getTime()) / 1000;
}
mandelbrot_run();
LapTop (12 Feb 2015)
====================
PHP7-JIT (JIT=on) 0.011
gcc -O2 (4.9.2) 0.013
LuaJIT-2.0.3 (JIT=on) 0.014
gcc -O0 (4.9.2) 0.022
HHVM-3.5.0 (JIT=on) 0.030
Java-1.8.0 (JIT=on) 0.059
LuaJIT-2.0.3 (JIT=off) 0.073
Java-1.8.0 (JIT=off) 0.251
PHP-7 0.281
squirrel-3.0.4 0.335
Lua-5.2.2 0.339
PHP-5.6 0.379
PHP-5.5 0.383
PHP-5.4 0.406
ruby-2.1.5 0.684
PHP-5.3 0.855
HHVM-3.5.0 (JIT=off) 0.978
PHP-5.2 1.096
python-2.7.8 1.128
PHP-5.1 1.217
perl-5.18.4 2.083
PHP-4.4 4.209
PHP-5.0 4.434
// by Erik Wrenholt
import java.util.*;
class Mandelbrot
{
static int BAILOUT = 16;
static int MAX_ITERATIONS = 1000;
private static int iterate(float x, float y)
{
float cr = y-0.5f;
float ci = x;
float zi = 0.0f;
float zr = 0.0f;
int i = 0;
while (true) {
i++;
float temp = zr * zi;
float zr2 = zr * zr;
float zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT)
return i;
if (i > MAX_ITERATIONS)
return 0;
}
}
public static void main(String args[])
{
Date d1 = new Date();
int x,y;
for (y = -39; y < 39; y++) {
System.out.print("\n");
for (x = -39; x < 39; x++) {
if (iterate(x/40.0f,y/40.0f) == 0)
System.out.print("*");
else
System.out.print(" ");
}
}
Date d2 = new Date();
long diff = d2.getTime() - d1.getTime();
System.out.println("\nJava Elapsed " + diff/1000.0f);
}
}
Copy link

ghost commented Mar 1, 2015

How badly did php5.0 mess up to be slower than php4.4?

@jpauli
Copy link

jpauli commented Mar 2, 2015

PHP5.0 is a joke.
More seriously, it is an extremely unoptimized version that added many features on top of PHP4, but with no performance consideration at all (that wasnt a goal at the time it was beeing hacked).
This all has changed starting from 5.1, which got released something like 16months after 5.0 , and started adding many optimizations.

@zsuraski
Copy link

zsuraski commented Mar 3, 2015

I wouldn't say it was a joke - but it introduced a lot of new features and radically different object model, with focus being on functionality. I think the major slowdown came from the new exceptions mechanism.
Note that the numbers here are quite misleading as with OO code, PHP 5 was actually faster than 4 because of the new object model; But this benchmark doesn't measure OO code at all.

Copy link

ghost commented Mar 17, 2015

Hey, that's not fair! Show the results for other python interpreters.

On my laptop -
Python - 1.04 sec
PyPy - 0.04 sec

@scoates
Copy link

scoates commented May 20, 2015

This is great. I'd been rendering mandelbrots asynchronously!
(-;

@rguillebert
Copy link

Where's PyPy?

@Eccenux
Copy link

Eccenux commented May 20, 2015

Try using float in C++. It should be about 10% faster and maybe even on top of the list.

Have you tried just running calculations and no printing? Most of the time spent is printing so you are actually testing the print/echo function.

@cortex93
Copy link

php output is buffered and as Eccenux already said it, most of the time is spent in writing output.
The result is useless but to compare php versions performance and php7 JIT optimizations are really impressive.

@SharpMan
Copy link

/laugh if you qualified this a 'benchmark'

@eau-de-la-seine
Copy link

Hi, for Java you should use the "final" keyword for BAILOUT and MAX_ITERATIONS.
Also its useless to instanciate new Date() for what you are doing, use System.currentTimeMillis() instead.

@eau-de-la-seine
Copy link

I haven't noticed you had "echo" / "println" in your code, put only 1 of those functions at the end for showing the duration and the result, otherwise you're benchmark is not reliable. Also, is it an average ? How many time have you launched those codes ?

@moltar
Copy link

moltar commented Jul 13, 2015

Improved Perl code, local here is not appropriate.

Also using Time::HiRes for accurate measurements. But that's optional.

$BAILOUT=16;
$MAX_ITERATIONS=1000;

use Time::HiRes qw(gettimeofday tv_interval);
$begin = [gettimeofday];

sub mandelbrot {
       my $x = $_[0];
       my $y = $_[1];

       my $cr = $y - 0.5;
       my $ci = $x;
       my $zi = 0.0;
       my $zr = 0.0;
       my $i = 0;

       while (1)
       {
               $i = $i + 1;
               my $temp = $zr * $zi;
               my $zr2 = $zr * $zr;
               my $zi2 = $zi * $zi;
               $zr = $zr2 - $zi2 + $cr;
               $zi = $temp + $temp + $ci;
               if ($zi2 + $zr2 > $BAILOUT)
               {
                       return $i;
               }
               if ($i > $MAX_ITERATIONS)
               {
                       return 0;
               }
       }
}

for ($y = -39; $y < 39; $y++)
{
       print("\n");
       for ($x = -39; $x < 39; $x++)
       {
               $i = mandelbrot($x/40.0, $y/40.0);
               if ($i == 0)
               {
                       print("*");
               }
               else
               {
                       print(" ");
               }
       }
}
print("\n");

$end = tv_interval ( $begin );

print "Perl Elapsed $end\n";

@jecolon
Copy link

jecolon commented Aug 21, 2015

Go 1.5 on a MacBook Pro; time: 0.010

package main

import (
    "bytes"
    "fmt"
    "time"
)

const (
    BAILOUT        = 16
    MAX_ITERATIONS = 1000
)

func main() {
    var buf bytes.Buffer
    startTime := time.Now()
    for y := -39.0; y < 39.0; y++ {
        for x := -39.0; x < 39.0; x++ {
            if iterate(x/40.0, y/40.0) == 0.0 {
                buf.WriteRune('*')
            } else {
                buf.WriteRune(' ')
            }
        }
        buf.WriteRune('\n')
    }
    fmt.Print(buf.String())
    fmt.Printf("\nGo Elapsed %.3f\n", time.Now().Sub(startTime).Seconds())
}

func iterate(x, y float64) float64 {
    cr := y - 0.5
    ci := x
    zr := 0.0
    zi := 0.0
    i := 0.0
    for {
        i++
        temp := zr * zi
        zr2 := zr * zr
        zi2 := zi * zi
        zr = zr2 - zi2 + cr
        zi = temp + temp + ci
        if zi2+zr2 > BAILOUT {
            return i
        }
        if i > MAX_ITERATIONS {
            return 0.0
        }
    }
}

@jecolon
Copy link

jecolon commented Aug 21, 2015

Go 1.5 using concurrency / parallelism. Time: 0.002 !!

package main

import (
    "bytes"
    "fmt"
    "strings"
    "time"
)

const (
    BAILOUT        = 16
    MAX_ITERATIONS = 1000
)

type line struct {
    number int
    text   string
}

func main() {
    out := make(chan *line, 80)
    startTime := time.Now()
    for y := -39.0; y < 39.0; y++ {
        // Fan out
        go lines(y, out)
    }
    // Fan in
    ls := make([]string, 80)
    for y := -39.0; y < 39.0; y++ {
        l := <-out
        ls[l.number+39] = l.text
    }
    fmt.Print(strings.Join(ls, ""))
    fmt.Printf("\nGo Elapsed %.3f\n", time.Now().Sub(startTime).Seconds())
}

func lines(y float64, out chan<- *line) {
    var buf bytes.Buffer
    for x := -39.0; x < 39.0; x++ {
        if iterate(x/40.0, y/40.0) == 0.0 {
            buf.WriteRune('*')
        } else {
            buf.WriteRune(' ')
        }
    }
    buf.WriteRune('\n')
    out <- &line{
        number: int(y),
        text:   buf.String(),
    }
}

func iterate(x, y float64) float64 {
    cr := y - 0.5
    ci := x
    zr := 0.0
    zi := 0.0
    i := 0.0
    for {
        i++
        temp := zr * zi
        zr2 := zr * zr
        zi2 := zi * zi
        zr = zr2 - zi2 + cr
        zi = temp + temp + ci
        if zi2+zr2 > BAILOUT {
            return i
        }
        if i > MAX_ITERATIONS {
            return 0.0
        }
    }
}

@gurinderu
Copy link

Java benchmark is wrong. Where is warmup?
I will try rewrite your benchmark for c too.

@gurinderu
Copy link

@dstogov

I fixed java benchmark, please run on your test machine and update results
https://github.com/gurinderu/benchmarks

@alexeyka119
Copy link

Hey, is this a purpose or a mistake that the file is called Mabdelbrot.java and not Mandelbrot.java?

@it2350
Copy link

it2350 commented Dec 28, 2015

Where did you get PHP7-JIT? There is no code for JIT in PHP7 at all !!!

@madlopt
Copy link

madlopt commented Oct 4, 2016

ob_start();
$m = new Mandelbrot();
ob_end_flush();

It's not fair test when PHP uses buffer and others not.

@thisisjeffsnow
Copy link

thisisjeffsnow commented Jun 11, 2023

The PHP code uses the old PHP 4 style constructor, which is removed in 8.0 onward.
You will want to change Mandlebrot() to __construct() for PHP 8.0+

https://www.php.net/manual/en/language.oop5.decon.php

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