Benchmark tra c, c ++, c #, python e go

benchmark.png

Condividi

10 luglio 2011, 22:36 – Aggiornato l’11 luglio 2011, 10:24

Dopo aver scritto la voce precedente sul linguaggio di programmazione Vai e la lettura di un linguaggio di programmazione Go Commenta dove si dice che vada è piuttosto lento, ho deciso di fare benchmark molto semplici.

L’idea è di confrontare la velocità di esecuzione del rimborso del logaritmo naturale di un dato numero e dell’introduzione di esso in una mappa o hash. Ovviamente, la velocità dipende in larga misura sull’attuazione del contenitore in ciascuna lingua.

Come per andare, ho utilizzato il compilatore 6G basato su Inferno perché non voglio installare una versione instabile del Compilatore GCC in Me Gentoo Linux e cattivandolo grande, aggiungendo il GCGO ottimizza il codice più di 6G.

Nota: questo benchmark è piuttosto squallido e Simplose, l’ho fatto per alleviare la mia curiosità e vedere più o meno da dove era la performance di Go. In futuro e quando ho più tempo, lo farò seriamente aggiungendo Java, Ruby e Scala.

Implementazione C

Cominciamo con l’attrezzo in c di Questo semplice benchmark. Ho usato le librerie di Uthash per creare l’hash, puoi trovarle in Sourceforge

codice becnhmark.c

compilation

genbeta@dev $ gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -std=c99 benchmark.cgcc -lm -o cbench benchmark.o

Implementazione C ++

per c ++ Utilizziamo il contenitore della mappa del codice Ben

Benchmark.cpp

#include <iostream>#include <map>#include <cmath>using namespace std;int main(){ map <float , float> dict; for (int i = 0; i < 5000000; i++) { dict = log(i); } return 0;}

compilation

genbeta@dev $ g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP benchmark.cpp -o cppbenchmark.og++ -o cppbench cppbenchmark.o

Implementazione in mono c #

Esperti in .NET C # Lasciami perdonami ma non ho idea di c # Non so se questo snippet è molto buono, ma il caso è che funzioni fantastico, se c’è qualche errore ti prego di correggere me.

benchmark.cs

using System;using System.Collections;namespace CSBenchmark{ class MainClass { public static void Main (string args) { Hashtable dict = new Hashtable(); for (int i = 0; i < 5000000; i++) { dict.Add(i, Math.Log(i)); } } }}

compilation

genbeta@dev $ /usr/bin/gmcs /noconfig "/out:./benchmark.exe" "/r:/usr/lib/mono/2.0/System.dll" /nologo /warn:4 /debug:+ /debug:full /optimize- /codepage:utf8 /platform:x86 "/define:DEBUG" /t:exe "./benchmark.cs"

Attuazione in Python

Questo è sicuramente il più semplice di tutti 🙂

codice di benchmark

import mathd = {}for i in range(1, 5000000): d = math.log(i)

Implementazione in Vai

Anche questo è molto semplice, è più o meno alla pari con C ++

benchmark.go codice

package mainimport "math"func main() { m := make(map float64) var i float64 = 1 for ; i < 5000000.; i++ { m = math.Log(i) }}

compilation

genbeta@dev $ 6g benchmark.go && 6l benchmark.6 && mv 6.out gobench

benchmarking

per l’esecuzione dei benchmark i Utilizzare il comando del tempo GNU sul seguente sistema:

  • Sistema operativo: Gentoo Linux
  • Architettura: x86_64
  • Processore: Intel® Core ™ I7 CPU @ 2.80GHz
  • velocità ram: 1666
LINGUA Tempo utente Sistema di tempo Tempo reale Utilizzo della CPU RAM usando Cambia contesto
C 1.90s 0,27S 2.19s 99% 1826704kb 1
C ++ 4.07S 0.14s 4.24S 99 % 941808kb 1
c # 1.72s 0,29 S 2.01s 131% 2032176kb 1155
python Cpy. Thon 2.7.2 3.43s 0.37s 3.86s 99% 2101312kb 1
PYTHON PYPY-C1.5 1.57S 0.33S 2.70s 99% 2442032kb 280
go 2.76S 0,16S 2.93S 99% 1044304KB 1

è degno di nota come C # è il più veloce con 2,01, non ho idea se è così per L’implementazione della scimmia, della lingua stessa, o se non ho fatto bene il benchmark in c # ma la verità è che sono piacevolmente colpito. È ancora vicino a C con 2.19s, quindi l’implementazione del python 2.7 di Python 2.7 con 2.70, dopo che ha un turno di andare con 2.93, l’implementazione di CPYTHON 2.7 continua con 3.86 e molto tristemente l’ultimo posto C ++ è occupato con A 4.24

Possiamo anche apprezzare come una scimmia e un pyyy utilizzare più di un nucleo del mio processore i7 mentre il resto utilizza solo un nucleo al 99%.

Per quanto riguarda il consumo di memoria, c ++ è il più ottimale strettamente vicino. C # e Python – in entrambe le implementazioni: fare un uso molto maggiore delle risorse.

Go Profiling

Ma occhio, che il benchmark è stato eseguito senza usare la profilazione in movimento. In movimento, gli strumenti di profilazione vengono utilizzati per rilevare i colli di bottiglia e fissarli notevolmente. La carta a cui un utente di cui al post precedente è un punto di riferimento senza profilatura in movimento e ha già avuto la sua risposta dai creatori della lingua nel blog ufficiale.Useremo la profilazione per vedere quanto possiamo migliorare le prestazioni del nostro snippet in movimento.

In primo luogo, modifichiamo il codice della nostra funzione per aggiungere supporto per cpuprophing, il nostro codice sarebbe come questo:

package main<br />import ( &#8220;math&#8221; &#8220;os&#8221; &#8220;flag&#8221; &#8220;log&#8221; &#8220;runtime/pprof&#8221;<br />)<br />var cpuprofile = flag.String(&#8220;cpuprofile&#8221;, &#8220;&#8221;, &#8220;write cpu profile to file&#8221;)<br />func main() { flag.Parse() if cpuprofile != &#8220;&#8221; { f, err := os.Create(cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } m := make(map float64)
 var i float64 = 1 for ; i < 5000000.; i++ { m = math.Log(i) }

}

Ora possiamo eseguire lo snippet con il Parametro CPUProfile e debug IT con GOPPROF:

./gobench -cpuprofile=gobench.profgopprof gobench gobench.profWelcome to pprof! For help, type &#39;help&#39;.(pprof) top10Total: 290 samples 149 51.4% 51.4% 224 77.2% hash_insert_internal 32 11.0% 62.4% 32 11.0% math.Log 17 5.9% 68.3% 17 5.9% runtime.mcpy 17 5.9% 74.1% 17 5.9% runtime.memmove 16 5.5% 79.7% 16 5.5% memhash 13 4.5% 84.1% 13 4.5% runtime.memclr 13 4.5% 88.6% 13 4.5% scanblock 8 2.8% 91.4% 250 86.2% runtime.mapassign 5 1.7% 93.1% 8 2.8% MHeap_AllocLocked 5 1.7% 94.8% 5 1.7% memwordcopy(pprof)

Possiamo vedere che l’applicazione occupa la maggior parte dei cicli della CPU e il runtime nell’inserimento dei valori Nella mappa. L’applicazione raffinata sviluppata in Vai a GOPPROF va ben oltre l’intenzione di questa voce, ma controllando gli annunci del codice e i campioni utilizzati in ciascuna linea possiamo sapere che il collo di bottiglia è sulla linea Accumula 285 dei 290 campioni dell’esecuzione.

È chiaro che l’uso di una mappa per questo benchmark non è nulla di ottimale e potremmo usare una fetta per memorizzare i dati. Se modifichiamo il file e commentiamo sulla riga /*m := make(map float64)*/ e utilizzare una fetta invece di una mappa var p float64; m := make(float64, len(p)) e generare un file .prof e noi SCORD:

Welcome to pprof! For help, type &#39;help&#39;.(pprof) top10 -cumTotal: 25 samples 7 28.0% 28.0% 25 100.0% main.main 0 0.0% 28.0% 25 100.0% runtime.initdone 0 0.0% 28.0% 25 100.0% runtime.mainstart 18 72.0% 100.0% 18 72.0% math.Log(pprof)

Controlliamo che ora la pratica del tempo è dedicata alla funzione che restituisce il logaritmo naturale di e non c’è più un collo di bottiglia. Elimineremo il codice che introdurremo la funzionalità di ristrutturazione commentando e passiamo di nuovo il benchmark.

LINGUA THE TIME Sistema di tempo TEME TEMPO UTILIZZO DELLA CPU UTILIZZARE RAM Cambia contesto
Vai 0,22S 0.01S 0.24S 99% 314512kb 1

Ouch! Un notevole miglioramento. Ma siamo giusti, cambieremo l’hash nell’attuazione di C da un semplice array e convertiremo il benchmark in calcolo semplicemente il logaritmo naturale di IE immettere il valore in un array.

LINGUA Tempo utente Sistema di tempo Tempo reale Utilizzo della CPU Uso della RAM Modifiche del contesto
C 0.31S 0.00S 0.31 S 99% 1824kb 1
go 0,22 s 0,01s 0,24s 99% 314512kb 1

In questo caso, vai è ancora più veloce di c che ritorna il logaritmo naturale di .

conclusione

Sembra che il tipo map non sia molto sottile in movimento, ancora, la velocità . La finzione linguistica è tra C e C ++. In questo caso, non possiamo fare nulla cento legittimo per eliminare il collo di bottiglia perché è una parte specifica del test che abbiamo fatto. Non so se devi aspettare quattro anni come ho letto lì che la lingua è più matura o meno. È chiaro che la scadenza non ha ancora bisogno e ha bisogno di alcune implementazioni nei sistemi per essere in grado di migliorare. Cosa succede se lo so è che sono almeno di seguire la pista, e più ora che è disponibile su Google App Engine ed è più efficiente di Python e Java.

More On Genbeta Dev |. Introduzione al linguaggio di programmazione Go

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *