Benchmark entre C, C ++, C #, Python e Go (Galego)

benchmark.png

Compartir

10 de xullo de 2011, 22:36 – Actualizado 11 de xullo de 2011, 10:24

Despois de escribir a entrada anterior sobre o idioma de programación ir e ler a Comentario onde se di que vaia é bastante lento, decidín facer benchmarks moi simples.

A idea é comparar a velocidade de execución do reembolso do logaritmo natural dun determinado número e a introdución dela nun mapa ou hash. Obviamente, a velocidade depende en gran medida da implementación do contenedor en cada idioma.

En canto a Go, usei o compilador 6G baseado en inferno porque non quero instalar unha versión inestable do GCC compilador en min Gentoo Linux e Shitting It Big, engadindo o GCGO optimiza o código máis de 6g.

Nota: Este punto de referencia é bastante malvado e simples, só o fixen para aliviar a miña curiosidade e ver máis ou máis Menos por onde foi o rendemento de Go. No futuro e cando teño máis tempo, vou facer un seriamente engadindo Java, Ruby e Scala.

Implementación C

Imos comezar coa implementación en C de Este simple referente. Eu usei as bibliotecas de Uthah para crear o hash, pode atopalos en SourceForge

Código BecNhmark.c

#include <math .h>#include "uthash.h"struct map { float id; float value; UT_hash_handle hh;};struct map *dict = NULL;void add_data(float data_id, float data){ struct map *m; m = malloc(sizeof(struct map)); m->id = data_id; m->value = data; HASH_ADD_INT( dict, id, m );}int main(){ for (int i = 0; i < 5000000; i++) { add_data(i, log(i)); } return 0;}

compilación

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

Implementación C ++

Para C ++ Usamos o recipiente de mapa do código 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;}

compilación

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

implementación en mono c #

Expertos en .NET C # Déixeme perdoame, pero non teño idea de C # Non sei se este fragmento é moi bo, pero o caso é que funciona moi ben, se hai algún erro que te pido a corrixir 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)); } } }}

compilación

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"

Implementación en Python

Esta é seguramente a máis sinxela de todo 🙂

código de referencia

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

implementación en Vaia

Isto tamén é moi sinxelo, é máis ou menos ao par de C ++

benchmark.go código

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

compilación

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

Benchmarking

Para a execución dos puntos de referencia I Use o comando de tempo GNU no seguinte sistema:

  • sistema operativo: Gentoo Linux
  • Arquitectura: x86_64
  • Procesador: Intel® Core ™ I7 CPU @ 2.80GHz
  • velocidade RAM: 1666
Idioma Equipo usuario Hora do Sistema Tempo real Usando CPU RAM Usando Cambios de contexto
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.76 0.16S 2.93s 99% 1044304KB 1

é de mención que C # é o máis rápido con 2.01, non teño ningunha idea se isto é así A implementación do mono, a linguaxe en si, ou se non fixen ben o referente en C #, pero a verdade é que estou moi impresionado. Aínda está preto de C con 2.19, a continuación, a implementación da pypy de Python 2.7 con 2.70, despois de que teña un xiro para ir con 2.93, a implementación de CPYTHON 2.7 continúa con 3,86 e moi tristemente o último lugar C ++ está ocupado con A 4.24

Tamén podemos apreciar como un mono e pypy usar máis dun núcleo do meu procesador I7 mentres que o resto só usa un núcleo nun 99%.

En canto ao consumo de memoria, C ++ é o máis óptimo estreitamente próximo por ir. C # e python – en ambas implementacións – facer un uso moito maior de recursos.

go perfilado

Pero o ollo, que o punto de referencia foi executado sen usar o perfil en ir. En Go, as ferramentas de perfilado úsanse para detectar botellas de botella e solucionalos mellorando considerablemente. O papel ao que un usuario a que se refire o post anterior é un referente sen perfilar en ir e xa tivo a súa resposta dos creadores da linguaxe no blog oficial.Imos usar perfilando para ver o que podemos mellorar o rendemento do noso fragmento en Go.

En primeiro lugar, modificamos o código da nosa función para engadir soporte para CPUPPROPHing, o noso código sería así:

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

}

Agora podemos executar o fragmento co CPUPROFILE PARAMETER E DEBUGLO CON GOPPROF: “03CD0954A3”>

Podemos ver que a aplicación ocupa a maioría dos ciclos da CPU e o tempo de execución ao entrar en valores No mapa. A aplicación refinada desenvolvida en Go con GopProf vai moito máis alá da intención desta entrada, pero comprobando as listas do código e as mostras utilizadas en cada liña podemos saber que o pescozo está na liña que acumulan 285 das 290 mostras da execución.

Está claro que o uso dun mapa para este punto de referencia non é nada óptimo e poderiamos usar unha porción para almacenar os datos. Se editamos o ficheiro e comentamos na liña /*m := make(map float64)*/ e use unha porción no canto dun mapa var p float64; m := make(float64, len(p)) e xerar un ficheiro .prof e nós Solicitar:

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)

Comprobamos que agora a práctica do tempo está dedicada á función que devolve o logaritmo natural de xa non hai botella de botella. Eliminaremos o código que introduce a funcionalidade de remodelación comentando e pasamos de novo o punto de referencia.

idioma hora de usuario sistema de tempo en tempo real usando CPU usando a memoria RAM cambios de contexto
GO 0.22S 0.01s 0.24S 99% 314512KB 1

Ouch! Unha notable mellora. Pero imos ser xusto, imos cambiar o hash na implementación de C por unha matriz simple e converter o punto de referencia para simplemente calcular o logaritmo natural de IE Introduza o valor nunha matriz.

iv Id = “B80A4334DD”

idioma hora de usuario sistema de tempo en tempo real usando CPU Uso de RAM Cambios de contexto
0.31s 0.00s 0.31 S 99% 1824kb 1 go 0.22 s 0.01S 0.24S 99% 314512KB 1

Neste caso, vaia é aínda máis rápido que C devolución do logaritmo natural de .

Conclusión

Parece que o tipo map non é moi fino en ir, aínda, a velocidade .. A ficción lingüística está entre C e C ++. Neste caso, non podemos facer nada cen lexítimos para eliminar o pescozo de botella porque é unha parte específica da proba que fixemos. Non sei se ten que esperar catro anos, xa que lin aí que a lingua é máis madura ou non. Está claro que a madurez aínda falta e necesita algunhas implementacións en sistemas para poder mellorar. E se eu sei é que eu son polo menos eu vou seguir a pista, e máis agora que está dispoñible en Google App Engine e é máis eficiente que Python e Java.

Máis sobre GENBETA DEV | Introdución á linguaxe de programación de go

Deixa unha resposta

O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *