guter Programmiersprachen-Benchmark



  • Könnt ihr mir einen guten Programmiersprachen-Benchmark empfehlen? Er sollte möglichst viele Sprachen wie C, C++, Java, C#, Common Lisp, Python, Delphi, OCaml, Fortran beinhalten, bei den jeweiligen Sprachen gut geschriebenen Code verwenden und möglichst viele Sprachanforderungen (Gleitkommaarithmetik, Integerarithmetik, Arrays, Listen, Multithreading, ...) abdecken.



  • Was ist ein Programmiersprachenbenchmark? Soll der dann auch alle verfügbaren Compiler-/Interpreterversionen abdecken? Oder nur einen speziellen Compiler? Oder wie stellst du dir das vor?



  • Ja, möglichst viele verschiedene verfügbare Compiler-/Interpreterversionen.



  • Ja, nee, schon klar...



  • Schau mal in der Ct nach, da gabs doch mal so nen legendären Vergleich ...
    Da wurden aber nur 5 "Sprachpackete" getestet glaub ich.
    was kam da dabei noch mal raus ?
    Microsoft Sprechen sind die Besten, und C# und Java schlagen C++ signifikant.
    (Und ja es ging um performance, nicht um entwicklungszeit ^^)

    Ich glaub allein schon de Rahmenbedingungen zu definieren um Aussage-kräftige Ergebnisse zu bekommen, würde jahre verschlingen ^^

    Ciao ...



  • RHBaum schrieb:

    C# und Java schlagen C++ signifikant.
    (Und ja es ging um performance, nicht um entwicklungszeit ^^)

    😮



  • warte bis chip.de einen artikel rausbringt wie, diese sprachen hassen die programmierer weil sie so schnell sind, der dürfte in etwa so gut sein wie der heise artikel. schon die frage nach den benchmarks ist unsinn weil jede sprache nicht alles performant abdecken kann, das wäre ja ein widerspruch.


  • Mod

    Hast du mal Google bemüht? Es gibt da eine ziemlich einfach zu findende Seite, die deine Kriterien ziemlich genau trifft.



  • SeppJ schrieb:

    Hast du mal Google bemüht? Es gibt da eine ziemlich einfach zu findende Seite, die deine Kriterien ziemlich genau trifft.

    Die Seite ist aber ein bisschen unfair was C und C++ anbelangt, weil da einfach mal SIMD-Libs geladen werden, um Berechnungen zu beschleunigen, was dann Sprachen ohne diese Libs ziemlich alt aussehen lässt und dass dann als Beweis genommen wird, dass C/C++ die schnellsten Sprachen sind.
    Teilweise wird da auch gcc mit llvm verglichen (siehe rust vs. C/C++). Leider ist der gcc llvm immer noch in vielen Belangen (wenn auch nicht viel) voraus.

    Wer das nicht im Auge behält, der interpretiert da nur Quatsch raus.
    Die Idee hinter dem Benchmark finde ich zwar gut, aber die Rahmenbedingungen sollten einfach fairer sein.



  • Ich weiß zwar nicht ob SeppJ und ShadowClone diese Seite meinten (weil sie ja leider nur um den heißen Brei schwafeln) aber hier ist eine Seite mit vielen Sprachen und verschiedenen Szenarien (Code einsehbar): http://benchmarksgame.alioth.debian.org/



  • markierung inner bank schrieb:

    Ich weiß zwar nicht ob SeppJ und ShadowClone diese Seite meinten

    Ja, genau die. Die muss man mit Vorsicht genießen, was C/C++ anbelangt.



  • In welche Richtung meinst du?
    Ich habe mir sie (C)Sourcen gerade mal angeschaut, zusätzlich zur Aussage "don't use language features" gibt das tatsächlich ein wenig objektives Bild, da malloc erfahrungsgemäß von jedem Compiler unterschiedlich optimistisch implementiert wird, und malloc wird da (naturgemäß) häufig benutzt, wenn auch in professionellen Programmen nie in dieser rohen Form.



  • Wutz schrieb:

    In welche Richtung meinst du?
    Ich habe mir sie (C)Sourcen gerade mal angeschaut, zusätzlich zur Aussage "don't use language features" gibt das tatsächlich ein wenig objektives Bild, da malloc erfahrungsgemäß von jedem Compiler unterschiedlich optimistisch implementiert wird, und malloc wird da (naturgemäß) häufig benutzt, wenn auch in professionellen Programmen nie in dieser rohen Form.

    Z. B. n-body:

    https://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=gcc&id=4

    C: 9,56 sec
    rust: 24,07

    Wenn du dir einfach die Zahlen anschaust, dann denkst du: rust wird total gehypt und nichts kommt an C/C++ an. Guckst du im Quellcode, dann siehst du, dass SIMD verwendet wird. Kein Wunder also, dass C so gut performt. Das ist für mich Trickserei, weil explizite SIMD-Befehle schon fast so etwas wie Inline-Assembler ist. Was hat das noch mit der Sprache zu tun?

    Dass rust mit SIMD auf dieselbe Performance kommt, zeigt dieser Blog-Eintrag:

    http://huonw.github.io/blog/2015/08/simd-in-rust/

    Du wirst diesen Source Code allerdings noch nicht im Benchmark Game finden, da dieser immer nur den stable-Zweig von rust verwendet und die SIMD-Lib von rust den Nightly-Zweig voraussetzt.



  • RHBaum schrieb:

    Microsoft Sprechen sind die Besten

    dann wissen wir ja, wer den test in auftrag gab, lol



  • ShadowClone schrieb:

    Wenn du dir einfach die Zahlen anschaust, dann denkst du: rust wird total gehypt und nichts kommt an C/C++ an. Guckst du im Quellcode, dann siehst du, dass SIMD verwendet wird. Kein Wunder also, dass C so gut performt.

    Da magst du recht haben, zumal die Autoren ja selbst fordern, keine Sprachfeatures zu benutzen.
    Ich kenne mich sehr gut in C aus, und IHMO kann ich bei anderen Codes kein SIMD entdecken, und auch da hat C schon Vorteile.
    Ich bin aber der Meinung, dass selbst dieser C-Vorsprung noch deutlich auszuweiten wäre, und dass eben mit gewöhnlichem C.
    Im Übrigen kann man das ganze SIMD Zeugs außen vor lassen, indem man geeignete Hardware wählt, also nicht den dort verwendeten Q6600 (4Cores,...).



  • Da wird aber AVX (AVX ist kein SIMD?) verwendet.



  • "Guter Programmiersprachen-Benchmark" ist ein Oxymoron

    Ein fairer Vergleich zwischen mehreren Sprachen ist nur möglich wenn man:
    1. ...bei jeder Sprache einen Entwickler hat der diese Sprache wirklich gut beherrscht
    2. ...neben Einzelszenarien auch typische Anwendungen berücksichtigt (unter gleichen Rahmenbedingungen bezüglich der Architektur)

    Und gerade 2. ist kaum mit sinnvollen Aufwand machbar. Doch gerade Anwendungen führen typische Performancetests wieder ad absurdum. So kenne ich einige Vergleiche zwischen C++, C# und Java, bei denen letztere gut darstehen. In der Praxis habe ich aber noch kaum einen Fall erlebt bei dem native Anwendungen langsamer als Anwendungen in C#/Java waren. Anderseits schrumpfen die Vorteile immer mehr, merkbar sind sie dennoch - dennoch können C#/Java bezogen auf die Entwicklungszeit wesentliche Vorteile haben, die die Nachteile mehr als ausgleichen.



  • Zeus schrieb:

    Da wird aber AVX (AVX ist kein SIMD?) verwendet.

    SIMD: Single Instruction Multiple Data

    Was macht man mit AVX? Mehrere Datenwerte (multiple data) mit einem einzigen Befehl (single instruction) bearbeiten. Also SIMD. Passt schon.

    AVX wird sogar auf der Wikipedia Seite zu SIMD erwähnt: https://en.wikipedia.org/wiki/SIMD



  • Wutz schrieb:

    Ich bin aber der Meinung, dass selbst dieser C-Vorsprung noch deutlich auszuweiten wäre, und dass eben mit gewöhnlichem C.

    Ich denke, das würde sich in Grenzen halten, da mit rust, so wie bei C/C++ Zero Costs die Maxime ist und auch immer weiter getrieben wird. Was das Optimieren angeht, so lässt sich auch beim Frontend-Compiler noch einiges machen (ich verfolge da die Entwicklung), sodass dem Backend-Compiler das Optimieren leichter fällt. Gerade weil rust Sicherheitsgarantien hat, kann der Compiler Dinge optimieren, die er sonst aus Sicherheitsgründen nicht tun würde. Ein Beispiel ist Aliasing. In rust kann man garantieren, dass dies nicht auftritt. Der Compiler kann folglich aggressiv optimieren. Mit C lässt sich das tatsächlich auch angeben (static Argument), aber hier muss der Compiler einfach dem Entwickler vertrauen. Wenn der Entwickler Mist geschrieben hat, hat man undefiniertes Verhalten. Genau aus dem Grund – und auch aus Kompatibilitätsgründen – findet man so etwas in der freien Wildbahn nicht. C++ hat dies ebenfalls nicht im Standard.

    Neben den Compiler-Optimirierungen wären da noch Lib-Optimierungen. Die Libs sind noch verhältnismäßig jung. Aus diesem Grund ist auch noch hier viel rauszuholen.



  • Ich rede nicht von technischer Optimierung durch Compiler- und sonstige nachgelagerte Optimierungen, sondern von fachlicher Optimierung (also vom Design vor dem Schreiben der ersten Zeile Code).

    /* The Computer Language Benchmarks Game
    * http://benchmarksgame.alioth.debian.org/
    
    contributed by Kevin Carson
    compilation:
    gcc -O3 -fomit-frame-pointer -funroll-loops -static binary-trees.c -lm
    icc -O3 -ip -unroll -static binary-trees.c -lm
    */
    
    #include <malloc.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct tn {
    	struct tn*    left;
    	struct tn*    right;
    	long          item;
    } treeNode;
    
    treeNode* NewTreeNode(treeNode* left, treeNode* right, long item)
    {
    	treeNode*    new;
    
    	new = (treeNode*)malloc(sizeof(treeNode));
    
    	new->left = left;
    	new->right = right;
    	new->item = item;
    
    	return new;
    } /* NewTreeNode() */
    
    long ItemCheck(treeNode* tree)
    {
    	if (tree->left == NULL)
    		return tree->item;
    	else
    		return tree->item + ItemCheck(tree->left) - ItemCheck(tree->right);
    } /* ItemCheck() */
    
    treeNode* BottomUpTree(long item, unsigned depth)
    {
    	if (depth > 0)
    		return NewTreeNode
    		(
    			BottomUpTree(2 * item - 1, depth - 1),
    			BottomUpTree(2 * item, depth - 1),
    			item
    		);
    	else
    		return NewTreeNode(NULL, NULL, item);
    } /* BottomUpTree() */
    
    void DeleteTree(treeNode* tree)
    {
    	if (tree->left != NULL)
    	{
    		DeleteTree(tree->left);
    		DeleteTree(tree->right);
    	}
    
    	free(tree);
    } /* DeleteTree() */
    
    int main(int argc, char* argv[])
    {
    	unsigned   N, depth, minDepth, maxDepth, stretchDepth;
    	treeNode   *stretchTree, *longLivedTree, *tempTree;
    
    	N = atol(argv[1]);
    
    	minDepth = 4;
    
    	if ((minDepth + 2) > N)
    		maxDepth = minDepth + 2;
    	else
    		maxDepth = N;
    
    	stretchDepth = maxDepth + 1;
    
    	stretchTree = BottomUpTree(0, stretchDepth);
    	printf
    	(
    		"stretch tree of depth %u\t check: %li\n",
    		stretchDepth,
    		ItemCheck(stretchTree)
    	);
    
    	DeleteTree(stretchTree);
    
    	longLivedTree = BottomUpTree(0, maxDepth);
    
    	for (depth = minDepth; depth <= maxDepth; depth += 2)
    	{
    		long    i, iterations, check;
    
    		iterations = pow(2, maxDepth - depth + minDepth);
    
    		check = 0;
    
    		for (i = 1; i <= iterations; i++)
    		{
    			tempTree = BottomUpTree(i, depth);
    			check += ItemCheck(tempTree);
    			DeleteTree(tempTree);
    
    			tempTree = BottomUpTree(-i, depth);
    			check += ItemCheck(tempTree);
    			DeleteTree(tempTree);
    		} /* for(i = 1...) */
    
    		printf
    		(
    			"%li\t trees of depth %u\t check: %li\n",
    			iterations * 2,
    			depth,
    			check
    		);
    	} /* for(depth = minDepth...) */
    
    	printf
    	(
    		"long lived tree of depth %u\t check: %li\n",
    		maxDepth,
    		ItemCheck(longLivedTree)
    	);
    
    	return 0;
    }
    

    Hier ist nichts von MMX, POPCNT usw. zu sehen und trotzdem sehe ich deutliche Schwächen beim Autor. Als Optimierungen sind ihm nämlich auch nur pthreads eingefallen (in einer erweiterten Variante dieses Beispiels)
    Verbesserungen im prinzipiellen Testdesign/umgebung sehe ich in
    - strikt-konformes C89 oder C99 (das verhindert nämlich alle Compilererweiterungen, 3Parties, asm- und sonstige sprachferne Geschichten)
    - als Testhardware einen reinen Single-Core Prozessor (auch ohne jegliches Hyperthreading) und keine neumodschen Prozessorbefehlssätze
    -> ich hab noch einen alten eeePC mit IntelAtom im Keller, der z.B. sollte für sowas gut (d.h. deutlich besser) geeignet sein als der o.g.

    Wenn ich mal viel Zeit habe, mache ich das vielleicht mal selbst irgendwann.


Anmelden zum Antworten