Compartir
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 ( “math” “os” “flag” “log” “runtime/pprof”<br />)<br />var cpuprofile = flag.String(“cpuprofile”, “”, “write cpu profile to file”)<br />func main() { flag.Parse() if cpuprofile != “” { 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 '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)
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.
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