Calcul Pi in c, go, python, JavaScript, Ducktape si Lua

Categorii: Programare

31-Mar-2020 19:35 - 124 vizionari

Curios sa vad cat de rapid este un calcul simplu in golang (limbajul go) fata de limbajul c si python, am creat un program de test, folosind un algoritm din 1655 al matematicianului John Wallis utilizat in estimarea numarului irational π (pi).

Go si C

Programul in go include si implementarea in c a algoritmului:


package main

/*

#cgo !windows CFLAGS: -std=c99 -O3 -Wall -Wno-unused-value -fomit-frame-pointer -fstrict-aliasing
#cgo windows CFLAGS: -O3 -Wall -Wno-unused-value -fomit-frame-pointer -fstrict-aliasing

static double calcul_pi(long int n) {
  double pi = 2.0;
  for(long int i=1;i<n;i++ ) {
    pi = pi * 2.0*i * 2.0*i / (2.0*i-1) /(2.0*i+1);
  }
  return pi;
}


*/
import "C"
import "fmt"
import "time"

func calcul_pi(n int) float64 {
	var pi float64 = 2
	for i := 1; i < n; i++ {
		pi = pi * 2.0 * float64(i) * 2.0 * float64(i) / (2.0*float64(i) - 1) / (2.0*float64(i) + 1)
	}
	return pi
}

func main() {
	fmt.Println("Start main")
	var N int = 300000000
	fmt.Printf("N = %d milioane\n", N/1000000)

	// time.Now().Nanosecond() are un BUG
	t1 := time.Now().UnixNano()
	var pi float64 = float64(C.calcul_pi(C.long(N)))
	t2 := time.Now().UnixNano()
	fmt.Printf("C:\tcalculat pi=%f in %.2f sec\n", pi, float64(t2-t1)/1e9)

	t1 = time.Now().UnixNano()
	pi = calcul_pi(N)
	t2 = time.Now().UnixNano()
	fmt.Printf("GO:\tcalculat pi=%f in %.2f sec\n", pi, float64(t2-t1)/1e9)

	// time.Now().Nanosecond() are un BUG
	t1 = time.Now().UnixNano()
	pi = float64(C.calcul_pi(C.long(N)))
	t2 = time.Now().UnixNano()
	fmt.Printf("C:\tcalculat pi=%f in %.2f sec\n", pi, float64(t2-t1)/1e9)

	t1 = time.Now().UnixNano()
	pi = calcul_pi(N)
	t2 = time.Now().UnixNano()
	fmt.Printf("GO:\tcalculat pi=%f in %.2f sec\n", pi, float64(t2-t1)/1e9)
}

La 300 de milioane de iteratii, rezultatul se obtine in 4.5-4.7 secunde:

Calcul pi in golang 

Observ ca programul in c este un pic mai rapid decat varianta in go.

Python

Acelasi algoritm scris in Python a durat 4.2-4.9 secunde pentru numai 9 milioane de iteratii si rezultatul dezamagitor se mentine pentru mai multe versiuni de Python:


import time
import sys

def Pi(N):
    print ("N = {:.0f} milioane".format(N/1000000))
    pi = 2.0
    i = 0
    t1 = time.time()
    while True:
        i = i + 1
        pi = pi * 2.0*i * 2.0*i / (2.0*i-1.0) /(2.0*i+1.0)
        if i == N:
            break
    t2 = time.time()
    durata = t2 - t1 #secunde
    print ("pi calculat: {:f} in {:f} secunde\t".format(pi, durata))

if __name__ == '__main__':
    print(sys.version)
    Pi(9000000)
    

Calcul pi in python 2.7

Calcul pi in python 3.7 

Calcul pi in python 3.8

Dar PyPy intrece Pythonul standard si are performante identice cu c si go:

Calcul pi in PyPy 7.3.0

JavaScript



function calcul_pi(N){
   console.log('N are', N/1e6, 'milioane');
   var pi = 2;
   t1 = new Date().getTime();
   var sec = 0;
   for(i = 1; i < N; i++){
      pi = pi * 2*i * 2*i / (2*i-1) /(2*i+1);
   }
   t2 = new Date().getTime();
   console.log('     pi=',pi);
   console.log('Math.PI=',Math.PI);
   console.log('durata [ms]:', (t2-t1));
   return pi;
}

In browser Mozilla 74.0 executia a durat 1.55 secunde pentru 9 milioane de iteratii si 4.58 de secunde pentru 300 de milioane de iteratii.

In Google Chrome 80.0.3987.149, durata a fost 1.52 secunde pentru 9 milioane de iteratii si 4.81 secunde pentru 300 milioane de iteratii.

Executia in JavaScript in browsere de web este la fel de rapida ca in programele compilate, rezulta ca programele JavaScript din browsere sunt compilate in memorie inainte de executie, la fel ca programele PyPy.

Am mai testat si executia in Ducktape (un interpretor de JavaScript) varianta golang, si pentru 9 milioane de iteratii durata este 7 secunde.

Lua

Un program scris in golang si care include un sistem de executie interpretata a limbajului Lua:


package main

import "fmt"
import "time"
import "github.com/yuin/gopher-lua"

var calcul_pi = `
--
-- program in Lua
--
N = 9000000
-- print(string.format('Calcul pi, n=%d milioane',N/1e6))
print('Calcul pi, n=' .. N/1e6 .. ' milioane')
pi = 2
for i=1,N do
	pi = pi * 2*i * 2*i / (2*i-1) /(2*i+1)
end
print('pi=', pi)

`

func main() {
	fmt.Println("Teste LUA")
	L := lua.NewState()
	defer L.Close()

	// time.Now().Nanosecond() are un BUG
	t1 := time.Now().UnixNano()
	if err := L.DoString(calcul_pi); err != nil {
		fmt.Println("Eroare in executie:\n", err)
	}
	t2 := time.Now().UnixNano()
	fmt.Printf("calculat pi %.2f sec\n", float64(t2-t1)/1e9)
}


Programul in Lua interpretat de sistemul scris in golang dureaza 5.96 secunde pentru 9 milioane de iteratii si este un pic mai lent decat varianta in Python.



Ultimele pagini: RSS

Alte adrese de Internet

Categorii

Istoric


Atentie: Continutul acestui server reprezinta ideile mele si acestea pot fi gresite.