Benchmark între C, C ++, C #, Python și Go

Benchmark.png

share

10 iulie 2011, 22:36 – Actualizat 11 iulie 2011, 10:24

După ce a scris intrarea anterioară despre limba de programare Go și citirea a Comentariu Unde se spune că Go este destul de lent, am decis să fac mai simple valori de referință.

Ideea este de a compara viteza de executare a restituirii logaritmului natural al unui număr dat și introducerea din ea într-o hartă sau hash. Evident, viteza depinde în mare măsură de implementarea containerului în fiecare limbă.

ca și pentru Go, am folosit compilatorul 6G bazat pe infern, deoarece nu vreau să instalez o versiune instabilă a GCC Compilomer din ME Gentoo Linux și scârțâind-l mare, adăugând GCGO optimizează codul mai mult de 6g.

Notă: Acest punct de referință este destul de ciudat și simploză, tocmai am făcut-o să-mi ameliorez curiozitatea și să văd mai mult sau mai puțin de unde a fost performanța lui Go. În viitor și când am mai mult timp, voi face una în serios prin adăugarea Java, Ruby și Scala.

Implementare C

Vom începe cu implementarea în C. acest simplu punct de referință. Am folosit bibliotecile UTHASH pentru a crea hash, le puteți găsi în Sourceforge

cod becnhmark.c

iv id = „88A82DDD132”

compilație

Implementare C ++

pentru C ++ Folosim codul de hartă al codului STL

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;}

compilație

Implementare în Mono C #

experți în .NET C # Lasă-mă să mă iert, dar nu am nici o idee despre C # Nu știu dacă acest fragment este foarte bun, dar cazul este că funcționează minunat, dacă există vreo eroare pe care ți-o implor să corectezi 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)); } } }}

Compilație

iv id = „17ac3af52b”

Implementare în Python

acest lucru este cu siguranță mai simplu de toate 🙂

cod de referință

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

implementare în Go

Acest lucru este, de asemenea, foarte simplu, este mai mult sau mai puțin la par cu C ++

Benchmark.Go Code

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

Compilatie

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

Benchmarking

pentru executarea criteriilor de referință I Utilizați comanda GNU Time în următorul sistem:

  • Sistem de operare: Gentoo Linux
  • Arhitectură: X86_64
  • Procesor: CPU Intel® Core ™ i7 @ 2.80GHz
  • RAM Speed: 1666

1155

Limba Ora utilizatorului Sistemul de timp timp real Utilizarea CPU RAM utilizând Context modificări
c 1.90s 0.27s 2.19s 99% 1826704KB 1
C ++ 4.07s 4.24s 99 % 941808KB 1
1.72s 0.29 S 2.01s 131% 2032176KB
Python Cpy. Thon 2.7.2 3.43s 0.37s 39% 2101312KB 1
Python Pypy-C1.5 1.57s 0.33S 2.70S 99% 2442032KB
2.76s 0.16 2.93s 99% 1044304kb 1

este demn de remarcat ca C # este cel mai rapid cu 2.01, nu am nici o idee dacă este așa pentru asta Implementarea maimuței, a limbii în sine sau dacă nu am făcut bine referința în C #, dar adevărul este că sunt plăcut impresionat. Este încă aproape de C cu 2.19s, apoi Python 2.7 de implementare Pypy cu 2.70, după ce are o rundă de a merge cu 2.93, implementarea lui CPYTHON 2.7 continuă cu 3,86 și foarte trist în ultimul loc C ++ este ocupat cu A 4.24

Putem aprecia, de asemenea, ca o maimuță și o utilizare picătoare mai mult de un nucleu al procesorului meu I7, în timp ce restul utilizează doar un nucleu la 99%.

privind consumul de memorie, C ++ este cea mai optimă apropiată de Go. C # și Python – în ambele implementări – face o utilizare mult mai mare a resurselor.

Go Profiling

Dar ochiul, acest punct de referință a fost executat fără a folosi profilul în mișcare. În Go, instrumentele de profilare sunt folosite pentru a detecta blocajele și pentru a le rezolva considerabil. Lucrarea la care un utilizator la care se face referire în postul anterior este un punct de referință fără a intra în mișcare și a avut deja răspunsul său de la creatorii de limbă din blogul oficial.Vom folosi profilul pentru a vedea cât de mult putem îmbunătăți performanța fragmentului nostru în jos

}

}

Acum putem rula fragmentul cu Parametrul CPUPROFILE și depanați-l cu GopProf:

./gobench -cpuprofile=gobench.profgopprof gobench gobench.profWelcome to pprof! For help, type 'help'.(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)

Putem vedea că aplicația ocupă majoritatea ciclurilor CPU și timpul de execuție în introducerea valorilor în hartă. Aplicația rafinată dezvoltată în Go cu GopProf depășește cu mult intenția acestei intrări, dar verificarea înregistrărilor codului și eșantioanele utilizate în fiecare linie putem ști că blocajul este pe linia care acumulează 295 de exemple de execuție.

Este clar că utilizarea unei hărți pentru acest punct de referință nu este nimic optimă și am putea folosi o felie pentru a stoca datele. Dacă editați fișierul și am comentat linia /*m := make(map float64)*/ și utilizați o felie în loc de o hartă var p float64; m := make(float64, len(p)) și generați un fișier .prof și noi Scold:

Welcome to pprof! For help, type 'help'.(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)

Noi verificăm că acum practica timpului este dedicată funcției care returnează logaritmul natural al și nu mai există nici un blocaj. Vom șterge codul care introduce funcția de renovare comentând și trecem din nou referința din nou.

Schimbările de context

ora utilizatorului Sistemul de timp timp real Utilizarea procesorului utilizând RAM
Go 0.22s 0.01s 0.24s 99% 314512KB 1

Ouch! O îmbunătățire remarcabilă. Dar hai să fim corecți, vom schimba hash în implementarea lui C printr-o matrice simplă și vom transforma punctul de referință pentru a calcula pur și simplu logaritmul natural al IE, introduceți valoarea într-o matrice.

DIV ID = „4DB5D70292”>

Timpul utilizatorului

Sistemul de timp timp real Utilizarea CPU Utilizarea RAM modificări de context c 0.31s 0.31 S 99% 1824kb 1 0.22 s 0.01s 0.24s 99% 314512KB

1

În acest caz, Go este chiar mai rapid decât C Returnarea logaritmului natural al i.

Concluzie

Se pare că tipul map nu este foarte subțire în Du-te, totuși, viteza ye . Limba ficționată este între C și C ++. În acest caz, nu putem face nimic o sută de legitimă pentru a elimina blocajele, deoarece este o parte specifică a testului pe care l-am făcut. Nu știu dacă trebuie să aștepți patru ani când am citit că limba este mai matură sau nu. Este clar că maturitatea încă lipsește și are nevoie de câteva implementări în sisteme pentru a putea îmbunătăți. Dacă știu dacă știu că sunt cel puțin am să urmez piesa și mai mult acum că este disponibil pe motorul Google App și este mai eficient decât Python și Java.

Mai multe despre Genbeta Dev | Introducere în limba de programare Go

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *