Benchmarkprogramm in C#

Ganz großes Tennis, OP. Es war schon immer eine gute Idee, wenn man Hilfe braucht, die Adressaten zu verarschen.
 
Knieto schrieb:
Also ich schicke euch mal meine Funktion die ich bisher gebastelt habe, wäre cool, wenn ihr mal drüber schauen könntet!

meine Variablen:

int num;
bool prime;
....

Knieto schrieb:
Nein das Programm ins Notepad ++kopiert, der macht da automatisch die Zahlen daneben?
Warum? Ist das von Bedeutung?

maxwell-cs schrieb:

Wahnsinn, spannender als der Tatort ;)
 
Darf ich mal fragen, was hier das Problem ist!?

Wieso glaubt man nicht das es aus dem Notepad kommt!
Habe es bei mir so im Visual Studio Express 2010 so rein geschrieben und dann kopiert!
Nur die Punkte habe ich dann gesetzt!

Der Code von dem Link funktioniert nicht, schon getestet, und habe auch gesehen, dass ich euch aus dem falschen Programm diesen gezeigt habe!
Hat also alles nicht mit verarsche zu tun!!! Warum regt ihr euch denn so auf?

Wusste ja nicht, dass obwohl man ein absoluter Anfänger ist, sich solche Kommentare gefallen lassen muss!
Ich kann nur sagen, dass wir nie zuvor je Methoden durch gesprochen haben!
Das soll eine Übung sein, die ich halt probiere zu lösen!

Ich danke trotzdem den Usern die mir versuchen zu Helfen und mir nicht jediglich Links schicken!

Und das Programm mit der While oder auch For Schleife bekomme ich schon hin, das Problem war hat lediglich die Methode.
Zumal ich diese Rechnung garnicht verstehe, wie dadurch eine Primzahl ermittelt werden kann!
Deswegen habe ich mal im Internet nach einem Funktionierenden Quellcode umgeschaut und das Programm drum herum kann ich selber schreiben!
Nur wie gesagt, dass Problem ist der Code von der Methode!

Wir haben auch nie von einer Umsetzung von pseudocode in den programm-code gesprochen!
Die anderen Rechnungen die wir vorher hatten, konnte ich mir so erklären! Da ich aber die IsPrime Methode nicht verstehe, kann ich das auch nicht umschreiben!?

Von PapstRatze

Im Forum gibt es die Möglichkeit Code entsprechend Formatieren zu lassen. (Das Rautensymbol) Beim nächsten mal dann :-) .

Verstehe ich leider nicht, würde diese Möglichkeit aber gerne nutzen?!?!
Oder wie darf ich das verstehen?

Also nochmal, ich versuche und will hier niemanden verarschen!!!!!

Und hoffe weiterhin, dass ich Unterstützung bekomme!
 
Knieto schrieb:
Darf ich mal fragen, was hier das Problem ist!?
Man wird hier im Forum im großen und ganzen recht nett Empfangen, einzig wichtig um solche meist etwas gehässigen Kommentare zu ersparen: "Eigeninitiative".

D.h. erst ausprobieren, ob der "Algorithmus" richtige Ergebnisse liefert, bevor du es erfragst. Auch Anfänger können hier fragen, aber auch hier gilt, erst informieren.

Knieto schrieb:
das Problem war hat lediglich die Methode.
Aber was eine Methode ist weißt du oder? Wenn es da noch hakt:
"Ganz allgemein ausgedrückt ist eine Methode ein Stück Programmcode, dass nach Wunsch aufgerufen werden kann. Dies ist vor allem praktisch, wenn etwas öfter benötigt wird. ... Das grundlegende Ziel von Methoden ist es Programmcode wiederverwendbar zu machen."[1]

Knieto schrieb:
Zumal ich diese Rechnung garnicht verstehe, wie dadurch eine Primzahl ermittelt werden kann!
Um das Programm zu verstehen und korrekt schreiben zu können, ist das aber unerlässlich. Eine Primzahl ist eine Zahl, die nur durch 1 und sich selbst Teilbar ist. Ergo kann man eine Primzahl dahingehend bestimmen, wenn man einfach mal dreist alles durchrechnet. Also die zahl (z.B. 13) durch 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 teilen und schauen, ob eine der Rechnungen aufging (kein Rest => zahl%i == 0). Da alle Zahlen, die durch 2 Teilbar sind (mit Ausnahme der 2) keine Primzahlen sind, kann man hier schon mal abkürzen und nachprüfen, ob die Zahl durch 2 Teilbar ist. Und so geht es weiter, man versucht unnötige Schritte zu umgehen, um das Programm schneller zu machen. Aber auch so eine Beschreibung kannst du mit deiner Lieblings-Suchmaschine finden.

Code im Forum darzustellen geht entweder in dem du den Code in so einen Block packst ["CODE"]["/CODE"] (ohne ") oder eben einfach den Button dafür verwendest, der genau diese Tags einfügt :)

[1]http://www.csharpme.de/eigene_methoden.php
 
Zuletzt bearbeitet: (Formatierungsarbeiten)
Knieto schrieb:
Deswegen habe ich mal im Internet nach einem Funktionierenden Quellcode umgeschaut und das Programm drum herum kann ich selber schreiben!

Öhm ja, kein kommentar...
Für mich hört sich dass so an als solltest du nochmal beim kleinen 1x1 anfangen...
Was ist eine methode, was eine schleife, call by reference, call by value etc. pp

zum "Benchmarken" kannste auch folgendes benutzen:
Code:
for (double i = 0; i < int.MaxValue; i++)
                {
                   i-= 0.8; 
                }

Sinn des benchmarkens ist es ja eine art Leistungstest zu schaffen um einen vergleich zu haben.
Das könnte sogar ein string zusammen bauen sein ;)
 
Zuletzt bearbeitet von einem Moderator:
So heute habe ich nochmal ein wenig Zeit gefunden, mir ein paar Grundlagen genauer anzuschauen!
Dann kenne ich noch nen Kumpel, der ein wenig C programmieren kann und habe Ihn mal um Rat gefragt!

Mein Code sieht jetzt folgender maßen aus:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Benchmark
{
    class Program
    {
       public static bool IsPrime(int zahl)
        {
            if (zahl < 2) return false;

            if (zahl % 2 == 0) return false;

            int nummer = (int)System.Math.Sqrt(zahl);

            for (int i= 3; i <= nummer; i = i + 2)

            if (zahl % i == 0) return false;
            return true;
        
        }
        static void Main(string[] args)
        {
            int zahl_1, zahl_2;
            bool prime;


            while (true)
            {
                Console.Clear();
                Console.WriteLine("1. Eingabe der unteren Grenze für den Test (min 0):");
                zahl_1 = Convert.ToInt32(Console.ReadLine());


                Console.Clear();
                Console.WriteLine("2. Eingabe der oberen Grenze für den Test (max 50000000):");
                zahl_2 = Convert.ToInt32(Console.ReadLine());

                Console.Clear();
                Console.WriteLine("3. Berechnung aller Primzahlen und Ausgabe der aktuellen Zeit \n   vor und nach der Berechnung");
                Console.WriteLine("\n\n");

                Console.WriteLine("Die Zeit vor der Berechnung beträgt: {0}", System.DateTime.Now);
                Console.WriteLine("\n");

                for (int i = 3; i <= zahl_2; i = i + 2)
                {

                    prime = IsPrime(i);

                    //if (prime == true)
                    //{
                       // Console.WriteLine("Die Zahl {0} ist eine Primzahl.", i);
                    //}
                    //else
                    //{
                    //Console.WriteLine("Die Zahl {0} ist leider keine Primzahl!",i);
                    //}

                }

                Console.WriteLine("\n");
                Console.WriteLine("Die Zeit nach der Berechnung beträgt: {0}",System.DateTime.Now);
               

                Console.ReadLine();
            }
        }
    }
}
Das untere, also die Ausgabe ob es eine Primzahl ist oder nicht, habe ich mal auskommentiert, da dass ja eigentluch nicht die Aufgabe war. Und ich es nur so mal rein gemacht habe.

Ich denke ich habe es soweit verstanden, außer leider immernoch nicht, warum ich eine Wurzel brauche?!
Wenn ich den Code der Methode richtig verstanden habe , benutze ich ja nicht umsont den Datentyp INT ( Ganze Zahlen)?!
Ich musste auch erstmal nachlesen was das % Zeichen hier
Code:
 if (zahl % 2 == 0) return false;
bedeutet!
Ich habe einmal die bedeutung Devisionsrest gefunden und als mathematischer Operant auch Modulo!
???

SO wenn ich also die Wurzel ziehe aus einer Zahl größer 2 muss ich danach immer nur von 3 an jede 2 Zahl nehmen. Denn wenn ich durch eine grade Zahl teilen kann, ist es nie eine Primzahl...

Jetzt da ich denke, dass ich so einigermaßen verstanden habe, möchte ich gerne noch ein kleines Feautre einbringen.
Wenn ich mir die Start und die Endzeit anzeigen lasse, kann ich dies erstens auch in ms machen lassen?
Und 2. kann ich eine Differenz aus den Zeiten bilden?
Also 19:00:00 beginn
und 19:00:13 Ende, dass ich das in der Console anzeigen lassen kann, dass es 13 Sekunden gedauert hat!

Ich danke euch für eure Geduld, gerade die Hilfe von PapstRatze und jetzt auch von Marguth haben mir geholfen!

Gruß und Danke
 
Man benutzt die Quadratwurzel, weil falls es Teiler gibt, die größer sind als die Quadratwurzel, es auch einen geben muss der kleiner ist und deshalb der größere Teiler uninteressant ist.

Zum Beispiel: Die Zahl 36 hat die Teiler 2, 3, 6, 12 und 18.
Die 6 ist die Quadratwurzel und man kann jedem Teiler <6 einen anderen Teiler >6 zuordnen, so dass beide zusammen 36 ergeben.
Diesen hat man aber mit der Division durch den kleineren Teiler quasi schon gefunden, also muss er nicht extra gesucht werden.
Und es reicht ja schon ein einziger Teiler, damit die zu überprüfende Zahl sicher keine Primzahl ist:

2 * 18 = 36
3 * 12 = 36
6 * 6 = 36
 
Knieto schrieb:
Ich habe einmal die bedeutung Devisionsrest gefunden und als mathematischer Operant auch Modulo!
Beides richtig. Rechnet man mit Modulo bekommt man den unteilbaren Rest, wenn man mit Ganzzahlen rechnen will.
Das müsstest du aber wissen, das macht man schon in der Grundschule so, weil man da zu Anfang keine Kommazahlen kennt.

Modulo hilft zu erkennen, ob eine Division ohne Rest durchgeführt werden kann, also komplett aufgeht.
8 % 4 = 0, weil 8 / 4 = 2, Rest 0 ist.
9 % 4 = 1, weil 9 / 4 = 2, Rest 1 ist.
 
Sieht schonmal sehr gut aus, folgende sachen fallen aber noch auf:

1.
int zahl_1 wird definiert aber nicht benutzt! (stattdessen benützt du feste 3 als startwert)

2.
Console.WriteLine("Die Zeit nach der Berechnung beträgt: {0}",System.DateTime.Now);

könntest du verbessern, indem du z.B. eine Stopwatch benutzt und die Zeit selbst misst (nicht sehr aufwändig)

3.
Beachte auch dass du nur die Leistung eines Threads der CPU mit diesem Benchmark misst!
D.h. der Vorteil einer Mehrkern-Cpu kommt hier nicht zur Geltung.

4.
du gibst an dass die obergrenze nur maximal 50 000 000 sein darf, allerdings prüfst du das nicht.


PS: sind nur Verbesserungsvorschläge/Anmerkungen.
 
Zuletzt bearbeitet von einem Moderator:
Hallo nochmal,

also ich bringe das Thema nochmal zur Sprache!
Also erstmal habe ich das Programm auch nach 09Marguth Anmerkungen probiert umgesetzt!
Außer den 2. Punkt, mit der Stop watch Funktion!
Da wir explizit diese nehmen sollten, die ich auch im Programm verwendet habe! Also ich gehe zumindest davon aus, denn das stand noch dabei, dass wir System.DateTime.Now verwenden sollen.

Jetzt habe ich allerdings einen gaaaaaaanz Grundlegendes Problem! Ich habe es voll verstanden wie die Primzahlenberechnung verläuft und abgearbeitet wird, allerdings brauche ich nochmal eure Hilfe bei dem Punkt, wofür das Programm in seinen Grundzügen gedacht ist!
Also zur Bestimmung der Geschwindigkeit der CPU.
Jetzt ist meine Frage, in welchem Verhältnis steht denn diese Berechnung? Also was soll mir die Zeit sagen?
USW... Ich habe das Programm zwar mit einigen Features versehen, aber ich denke ich bin bissl am Thema vorbei?!

Danke im voraus

Edit:
Das Programm stelle ich gleich mal rein!
 
Das Ergebnis hat erst mal keine Aussagekraft. Du musst das Programm mit mehreren CPUs testen und dann kannst du die Zahlen miteinander vergleichen und somit bestimmen, welche CPU "schneller" ist, also dein Programm schneller ausführen kann.
 
Anbei mein Code:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Benchmark
{
    class Program
    {
        public static bool IsPrime(int zahl)
        {
            if (zahl < 2) return false;

            //if (zahl % 2 == 0) return false;

            int wert = (int)System.Math.Sqrt(zahl);

            for (int i = 2; i <= wert; i = i + 1)

            if (zahl % i == 0) return false;
            return true;

        }
        static void Main(string[] args)
        {
            try
            {
                int zahl_1, zahl_2;
                bool prime, auswahl = true;


                while (auswahl)
                {
                    Console.Clear();
                    Console.WriteLine("1. Eingabe der unteren Grenze für den Test (min 0):");
                    zahl_1 = Convert.ToInt32(Console.ReadLine());

                    if (zahl_1 % 2 == 0) zahl_1 = zahl_1 + 1;

                    while (zahl_1 < 0)
                    {
                        Console.BackgroundColor = ConsoleColor.DarkBlue;
                        Console.Clear();
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\n\n\n\n\n\n\n\n");
                        Console.WriteLine("\t\t\t\tLEIDER falsche Eingabe");
                        Console.ResetColor();
                        Console.ReadLine();
                        Console.Clear();
                        Console.WriteLine("1. Eingabe der unteren Grenze für den Test (min 0):");
                        zahl_1 = Convert.ToInt32(Console.ReadLine());
                    }


                    Console.Clear();
                    Console.WriteLine("2. Eingabe der oberen Grenze für den Test (max 50000000):");
                    zahl_2 = Convert.ToInt32(Console.ReadLine());

                    while (zahl_2 > 50000000)
                    {
                        Console.BackgroundColor = ConsoleColor.DarkBlue;
                        Console.Clear();
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("\n\n\n\n\n\n\n\n");
                        Console.WriteLine("\t\t\t\tLEIDER falsche Eingabe");
                        Console.ResetColor();
                        Console.ReadLine();
                        Console.Clear();
                        Console.WriteLine("2. Eingabe der oberen Grenze für den Test (max 50000000):");
                        zahl_2 = Convert.ToInt32(Console.ReadLine());
                    }



                    Console.Clear();
                    Console.WriteLine("3. Berechnung aller Primzahlen und Ausgabe der aktuellen Zeit \n   vor und nach der Berechnung");
                    Console.WriteLine("\n\n");
                    Console.WriteLine("Die Zeit vor der Berechnung beträgt: {0}", System.DateTime.Now);
                    Console.WriteLine("\n");
                    Console.Write("Der Zahlenbereich von {0} bis {1} enthält folgende Primzahlen: ", zahl_1, zahl_2);

                    for (int i = zahl_1; i <= zahl_2; i = i + 1)
                    {

                        prime = IsPrime(i);

                        if (prime == true)
                        {
                            Console.Write("{0} ", i);
                        }
                        //else
                        //{
                        //Console.WriteLine("Die Zahl {0} ist leider keine Primzahl!",i);
                        //}

                    }

                    Console.WriteLine("\n\n");

                    Console.WriteLine("Die Zeit nach der Berechnung beträgt: {0}", System.DateTime.Now);
                   


                    Console.ReadLine();

                    //wiederholen oder abbrechen
                    Console.Clear();
                    Console.Write("\n\n\nNochmal berechnen? Ja (j)");
                    if (Console.ReadLine() != "j")
                        auswahl = false;
                }
            }



            catch
            {
                Console.WriteLine("\n\n\n\n\n\nFalsche Eingabe");
                Console.ReadLine();
            }

        }
    }
}
Zeile 14 ist auskommentiert da ich mir nicht genau sicher bin ob 2 nun eine Primzahl ist oder nicht ?!
bitte einmal um durchsicht

Danke!!
 
Die 2 ist eine Primzahl. Schon immer gewesen. ;)
"Eine Primzahl ist eine positive Ganzzahl größer 1, die nur durch sich selbst und 1 teilbar ist"
Die 2 erfüllt diese Bedingungen.


Ich würde die Eingabe generischer basteln. Du könntest da eine Methode a la private static int GetIntegerInput(string text) schreiben, der du nur übergibst, was sich bei der Meldung der unteren und der oberen Grenze im Text ändert. Die Rückgabe kommt wie gewohnt in zahl_1 bzw. zahl_2.

Apropos Variablennamen: Es ist gängige Konvention sprechende Namen für alles (Methoden, Variablen, etc.) zu verwenden. Da rafft dann auch ein anderer Programmierer schnell, was du geschrieben hast.
Also statt zahl_1 bzw. zahl_2 eher untererDefinitionsbereich bzw. obererDefinitionsbereich schreiben. Beliebt sind auch englische Ausdrücke, wie zB hier das passende lowerBoundary und upperBoundary.

Weiterhin sind so große Methoden, wie du sie hier geschrieben hast, nicht gerne gesehen. Deine Main-Methode ist ca. 100 Zeilen lang, das ist deutlich zu viel. Die Faustregel ist, dass eine Methode komplett auf einen Bildschirm passen muss, also im Schnitt ca. 40-60 Zeilen. Ist sie länger, sollten Teile in andere Methoden ausgelagert werden.
Man macht das, damit die Übersichtlichkeit gewahrt wird. Du fängst gerade erst mit dem Programmieren an, dir wird das nicht wie ein Problem vorkommen. Wenn du später dann mal an größeren Programmen mit >10.000 Zeilen Code arbeitest, greifst du nach jedem Strohhalm, der dir beim Durchblick irgendwie hilft.

Das Auslagern in verschieden (Unter-)Methoden hilft dir auch, ein Programm in seine verschiedenen Aufgaben und Teilbereiche zu splitten. Alles was thematisch zusammen gehört, einfach in eine Methode packen.
Die Primzahlberechnung würde ich zB in zwei Methoden unterteilen. Eine, ich nenne sie mal calculatePrimes(int lowerBoundary, int upperBoundary), beinhaltet die For-Schleife für den Definitionsbereich. Die eigentliche Untersuchung, ob eine Zahl prim ist oder nicht, würde ich genau so machen, wie du es hier im Code zu stehen hast.
Das Aufsplitten des Codes und die Zusammenfassung in thematisch zusammengehörenden Einheiten ist auch eine gute Vorbereitung für das Erlernen der objektorientierten Programmierung.
 
Zuletzt bearbeitet:
Zu der Ausführung von e-Laurin ist eigentlich nichts mehr hinzuzufügen, außer die Zeilen 18-21: Diese muss man sich schon drei Mal durchlesen um zu verstehen, was hier passiert. Hier ist weder der Zeilenabstand noch die Einrückung sinnvoll gewählt. Geschweifte Klammern fördern auch gerne mal die Lesbarkeit, auch wenn Sie syntaktisch nicht benötigt werden.

Sonstiges zum Thema Code-Style: Mach' aus
Code:
i = i + 1;
if (Console.ReadLine() != "j")
das hier:
Code:
i++;
if (!"J".Equals(Console.ReadLine(), StringComparison.CurrentCultureIgnoreCase)){} // weil ReadLine() auch null zurück liefern kann!
 
Zurück
Oben