Wie schlecht ist mein Code wirklich?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Wie schlecht ist mein Code wirklich?

    Hallo

    Ich bin neu in der XCode Entwicklung.
    Um niemanden unnötig mit Anfängerfragen zu nerven (für "wieso geht mein NSArray nicht" gibt es schliesslich Google),
    habe ich meine Library bereits auf einen lauffähigen Stand gebracht, sie liefert zudem korrekte Ergebnisse.

    Allerdings gehe ich davon aus, dass der Code 'grottenschlecht' ist (gemessen an professionellen Standards), zu lange dauert und zu viel Speicher verschwendet.
    Er wurde nach bestem Wissen und Gewissen erstellt, allerdings ist das Wissen in Objective-C noch sehr gering.

    Ich habe tiefere Kentnisse von VBA (meist Excel), sowie einige Erfahrungen mit C, C++, PHP, Assembler, etc
    habe nun aber 5 sehr harte Wochen hinter mir, einfachste Funktionen zum laufen zu bringen, da in Objective-C alles ganz anders ist...
    Den Umstieg hatte ich mir ehrlich gesagt etwas einfacher vorgestellt.

    Nun ja, es ist noch kein Meister vom Himmel gefallen.
    Bevor ich weitere Teile des Projektes umsetze, würde ich gerne in die Runde fragen,
    welche Verbesserungsvorschläge es gibt bzw. was erfahrene XCode-Entwickler anders machen würden...

    Dann kann ich dies gleich beheben und mache es bei den nachfolgenden Libraries nicht erneut falsch
    (bitte bei den Antworten bedenken, dass ich mich noch nicht wirklich an Fachbegriffe und Syntax gewöhnt habe).

    Schliesslich plane ich noch viele weitere Programme in der XCode-Welt und es wäre schade
    erst ganz am Ende zu lernen, dass man alles hätte anders machen sollen...


    Hier der Code des Aufrufs meiner Library (im Original sieht die Formatierung besser aus)
    Zum Test werden alle Kombinationen von 7-Karten Texas Hold'em erzeugt und die Rückmeldung ausgewertet,
    wie oft Paar, Drilling, Strasse, etc vorkommen.
    Die Library (.h und .m) befinden sich in der angehängten .txt

    //!! TEST
    NSLog(@"Start");
    SCRanking *TestHand = [SCRanking new];

    NSMutableArray *Cards;
    Cards = [[NSMutableArray alloc] initWithObjects: @0,@0,@0,@0,@0,@0,@0, nil];
    int Table[10] = {0};
    int Count = 0;

    //inverse loops (from high to low numbers)
    //so the array is already pre-sorted
    for(int C0=51; C0 >= 4; C0--)
    {
    [Cards replaceObjectAtIndex:0 withObject:[NSNumber numberWithInteger:C0]];
    for(int C1=C0-1; C1 >= 3; C1--)
    {
    [Cards replaceObjectAtIndex:1 withObject:[NSNumber numberWithInteger:C1]];
    for(int C2=C1-1; C2 >= 2; C2--)
    {
    [Cards replaceObjectAtIndex:2 withObject:[NSNumber numberWithInteger:C2]];
    for(int C3=C2-1; C3 >= 1; C3--)
    {
    [Cards replaceObjectAtIndex:3 withObject:[NSNumber numberWithInteger:C3]];
    for(int C4=C3-1; C4 >= 0; C4--)
    {
    [Cards replaceObjectAtIndex:4 withObject:[NSNumber numberWithInteger:C4]];
    for(int C5=C4-1; C5 >= 0; C5--)
    {
    [Cards replaceObjectAtIndex:5 withObject:[NSNumber numberWithInteger:C5]];
    for(int C6=C5-1; C6 >= 0; C6--)
    {
    [Cards replaceObjectAtIndex:6 withObject:[NSNumber numberWithInteger:C6]];

    int HandValue = [TestHand GetHandValue: [Cards copy]];
    int Pointer = HandValue/1000000; //get type of hand
    Table[Pointer] += 1; //Count each result individually
    Count += 1; //Count summary of results
    }}}}}}}
    NSLog(@"End");
    Dateien
    • SCRanking v001.txt

      (23,66 kB, 287 mal heruntergeladen, zuletzt: )
  • Ja. Davon sind 23.294.460 "High Card", 58.627.800 "Pair", 31.433.400 "Two Pair", 6.461.620 "Three-of-a-Kind", 6.180.020 "Straight", 4.047.644 "Flush", 3.473.184 "Full House", 224.848 "Four-of-a-Kind", 37.260 "Straight Flush" und 4.324 "Royal Flush".
    Die Zahlen stehen nach Ausführung auch so in der Variable "Table", wobei letztere beiden zusammen gefasst werden (Royal Flush zählt als "Straight Flush auf Ass").

    Allerdings benötigt meine Objective-C Version 3:20min mit 18MB Memoryauslastung, während die Library in C++ nur 0:36min benötigt bei 0.5MB Memory.
    Daher nehme ich an, dass ich so einiges falsch gemacht habe, auch wenn das Programm an sich funktioniert...
  • Stormcastle schrieb:

    Daher nehme ich an, dass ich so einiges falsch gemacht habe, auch wenn das Programm an sich funktioniert...

    Durch das durchweg dynamische Dispatching ist Objective-C prinzipiell langsamer als C++. Solange Du in beiden Sprachen den gleichen Algorithmus verwendest, kannst Du den Geschwindigkeitsunterschied darauf zurückführen.
    „Meine Komplikation hatte eine Komplikation.“
  • Genereller Hinweis:

    Formulier als erstes Dein Problem so allgemein wie möglich. Was Du suchst, sind eigentlich alle 52-über-7 Kombinationen.
    Das klingt nach etwas, was man häufiger gebrauchen kann, warum also nicht eine Funktion für alle n-über-k Kombinationen?
    Das klingt nach etwas, was schon hundert mal gemacht wurde und man will ja das Rad nicht (eckiger) neu erfinden.
    Also einfach mal Google bemühen, um n-über-k Algorithmen zu finden.

    Dann kannst Du Dein Code so umbauen, dass Du eine Funktion hast, die über alle n-über-k Kombinationen iteriert. Die packst Du meinetwegen irgendwo anders hin, weil das ist ja viel allgemeiner als das Problem, was Du lösen willst.
    Diese Funktion rufst Du dann in Deinem Code auf. Dann weisst Du auch noch Jahre später, was hier passiert, anstelle zu rätseln, was C0-1 und so weiter soll.
    C++
  • zerm schrieb:

    Was Du suchst, sind eigentlich alle 52-über-7 Kombinationen.
    Das klingt nach etwas, was man häufiger gebrauchen kann, warum also nicht eine Funktion für alle n-über-k Kombinationen?

    Ganz so einfach ist es nicht. n über k gibt ja nur die Gesamtanzahl der Kombinationen an, aber nicht welche Hände nun wie oft vorkommen.
    Obige Schleifen sind aber nur ein Beispiel, wie man die Library nutzen könnte (diese nutze ich zum Debuggen und als Benchmark für Zeit-Optimierungen).
    Die C++ Version nutze ich seit längerem, um unter anderem Wahrscheinlichkeiten bestimmter Hände zu berechnen.

    Im Prinzip spielt es aber keine Rolle, was das Programm nun tut.
    Ich hätte jede andere Library zur Übung konvertieren können.
    Das Ziel ist ja nicht, die beste Poker-Library zu erstellen (da ist C++ schneller), sondern Objective-C zu lernen.

    Meine Frage zielt eher darauf, welche Fehler ich bei der Objective-C Konvertierung machte.
    Gibt es dort andere Konventionen, gibt es bessere Arten, den Code zu gestalten, welche Optimierungen gibt es die ich noch nicht kenne, etc.?
    Inwieweit würde der Code anders aussehen, falls ein erfahrener XCode-Programmierer diesen erstellt hätte?
    (in ein paar Monaten/Jahren werde ich ihn sicher auch anders schreiben, und diesen Lernprozess möchte ich etwas beschleunigen).

    Bitte schaut über die Library ähnlich einem Lehrer, der seinen Schülern Mathe beibringt.
    Ich bin in diesem Beispiel wohl der Erstklässler, der noch mit den Fingern zählt...
  • Stormcastle schrieb:

    Ganz so einfach ist es nicht. n über k gibt ja nur die Gesamtanzahl der Kombinationen an, aber nicht welche Hände nun wie oft vorkommen

    n-über-k berechnen ist trivial. Natürlich meinte ich, über alle möglichen Kombinationen zu iterieren, also genau das, was Du mit irgendwie sieben schleifen machst. Ich hatte gedacht, das wäre klar.
    Entsprechend lässt sich dann z.B. rosettacode.org/wiki/Combinations finden.

    Stormcastle schrieb:

    Meine Frage zielt eher darauf, welche Fehler ich bei der Objective-C Konvertierung machte.

    Sieben Schleifen und Variablennamen a la C0 macht man nicht. Also, Du möchtest, dass man ignoriert, was generell schlecht ist und nur kritisiert, was in Objective-C schlecht ist?
    C++
  • @macmoonshine: Da ich nun meine vielen kleinen Tools (die alle nur per Eingamemodus laufen) in einer größeren App verbinden möchte, die im iPhone läuft, komme ich wohl nicht um Objektive-C herum. Allerdings wollte ich das schon immer lernen, so dass diese App (ob sinnvoll oder nicht) eine gute Einsteiger-Übungsaufgabe ist.

    @zerm: Du kannst mich auch gerne bei anderen Fehlern korrigieren. Ich habe mir das programmieren selbst beigebracht. Da schleichen sich mit der Zeit sicher etliche Angewohnheiten ein, bei denen professionelle C-Programmierer sich am liebsten die Augen zuhalten...
    Meine hier eingereichten Programme stehen zur freien Diskussion und ich nehme jeden Verbesserungsvorschlag dankend an (unabhängig, ob es die Objective-C Syntax betrifft, C++, meine Art der Kommentierung, etc, etc). Ich bin schliesslich hier um zu lernen.

    //edit: Dein Link zum Rosettacode ist ein sehr gutes Beispiel. Kannte ich nicht. Finde ich sehr genial (jetzt wo ich verstanden habe, was du meinst)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von Stormcastle ()

  • macmoonshine schrieb:


    Wie gesagt: Du kannst problemlos Objective-C und C++ mischen.

    Ich habe in der Library versucht, meinen C++ Code weitestgehend beizubehalten.
    Xcode meckerte aber an vielen Stellen, so dass ich das nach und nach umschrieb, bis es wieder lauffähig war.

    Ich weiss zwar, dass man das mischen kann, aber mir fehlt noch die Erfahrung,
    welchen Code man in C++ lassen kann, welchen man besser ersetzen sollte.
    Ich weiss lediglich, welchen man ersetzen muss (da Xcode meckert)...
    ob meine Art das umzuschreiben jedoch "sauber" war, ist fraglich.
  • Ursprünglich war das ganze auf einem Windows System in einzelne Dateien ausgelagert, die ich jeweils über "import file.c" einband.
    Als ich auf Mac umstieg, funktionierte das bei XCode leider nicht mehr, so dass ich mir mit einer sehr langen main.cpp behalf.
    Erst kürzlich kaufte ich mir "iPhone Apps Programmieren" von Holger Hinzberg,
    dort lernte ich, dass man eine .h und eine .m erstellen muss und das Interface entsprechend deklarieren.

    Gefällt mir sehr gut.
    Ist anfangs gewöhnungsbedürftig, aber die Objekte sind einfacher handzuhaben als etliche kleine Funktionen,
    bei denen man irgendwann den Überblick verliert...

    Eine der Dinge, die angemeckert wurden, war die Übergabe von "int[]", das musste ich alles auf NSArrays umschreiben.
    Und statt "Cards[0] = C0" benötige ich nun "[Cards replaceObjectAtIndex:0 withObject:[NSNumber numberWithInteger:C0]];"
    da man keine Zahlen mehr zuweisen kann...
    Innerhalb der Library habe ich dann alles wieder mit "CardsSorted = [Cards[i] intValue];" extrahiert,
    da meine weiteren Funktionen noch größtenteils C++ sind und wieder "int[]" benötigen.
    Ob dieses hin-und-her so sauber von statten ging, darf hinterfragt werden...

    Ein Beispiel, wozu ich die Libraries bisher verwendete, ist hier zu sehen: Buchty.com/PokerRegeln.pdf
    Da das mittlerweile zu viele Seiten und zu viele Tabellen sind (und in den nächsten Monaten kräftig wächst),
    möchte ich eine App schreiben, die mir die nötigen Werte nach Eingabe der Karten liefert.
    (gibt es sicher auch schon im AppStore, aber man soll ja nur den Statistiken trauen, die man selbst gefälscht hat).
  • Stormcastle schrieb:

    dort lernte ich, dass man eine .h und eine .m erstellen muss und das Interface entsprechend deklarieren.

    Wenn du statt .m die Endung .mm verwendest, hast du in der Regel eine Objective-C++-Datei. Darin kann dein Code dann C++-Klasse ansprechen. C++-Dateien kannst du auch problemlos zu deinem Projekt hinzufügen.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:


    Wenn du statt .m die Endung .mm verwendest, hast du in der Regel eine Objective-C++-Datei. Darin kann dein Code dann C++-Klasse ansprechen. C++-Dateien kannst du auch problemlos zu deinem Projekt hinzufügen.


    [media]https://www.youtube.com/watch?v=YIj0qhYzqCU[/media]

    //edit: Ich lese mich gerade ein und es gibt im Netz viel Gegenwind bei .mm Dateien, viele halten sie für "Pfusch"
    Beispiel: robnapier.net/wrapping-cppfinal-edition

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Stormcastle ()

  • Ich werde mal googeln, wie man die C-Funktionen deklarieren muss, um sie in Objekten zu nutzen (auch mit +/- davor?) und dann das ganze wieder in einfaches C++ umschreiben (es werden ja nur ein paar Werte 0-51 hin und her geschoben, keine komplexen Objekte, da wird C++ für die Library sicher sinnvoller sein).

    Wobei die Lernphase mit NSArrays ja nicht ganz verkehrt war, die werden sicher im weiteren Projekt auftauchen, wenn ich die Basis-Libraries zu größeren Programmen verbinde...

    Gibt es weitere grobe Patzer, wie "zerm" einen fand?
    Das werde ich gleich mit in die nächste Version einfliessen lassen.