Laden...

Profil von Stefan S.

myCSharp.de - Member Mitglied seit
S
Stefan S.
myCSharp.de - Member
2
Themen
72
Beiträge
Dabei seit
20.05.2006
Letzte Aktivität
vor 13 Jahren
Herkunft
Capital City of Bavaria
Erstellt vor 13 Jahren

Es wundert mich das noch keiner geantwortet hat. Ich nutze die Library recht häufig. Respekt für die Arbeit an den Autor!

Die Software ist sehr sauber und logisch geschrieben. Ich habe lediglich bei den Matrizenoperationen ein paar performantere Algorithmen, z.B. den Strassen-Algorithmus, eingebaut.

Für einen E-Technik Absolventen jedenfalls ein schönes Stück Software. Da kann sich so manch ein Informatiker eine Scheibe von abschneiden.

Erstellt vor 13 Jahren

Der Strang ist zwar schon alt, aber für das Protokoll. Ich fand den folgenden Artikel dazu recht gelungen.

Künstliche neuronale Netze in C#

Da ist auch eine umfassende Bibliothek dabei für KNNs, gecodet in C#. Auch die OCR kommt da zur Sprache. Eignet sich daher recht gut für Präsentationen.

Erstellt vor 14 Jahren

Ein paar Aspekte, die Properties etwas kritischer beleuchten ohne sie für obsolet zur erklären.
*Ein Property kann schreibgeschützt sein oder darf nur beschrieben, aber nicht gelesen werden. Felder können immer gelesen und beschrieben werden. Das kann zu Verwirrungen im Code führen. *Ein Property kann eine Ausnahme auslösen, ein Feld nicht. *Ein Property kann nicht als out- oder ref-Argument übergeben werden. *Ein Property kann langsam beim Zugriff sein, die Entscheidung obliegt Designkriterien und dem Compiler, ob ein Inlining stattfindet. *Properties geben beim Zugriff mit einem Thread nacheinander eventuell unterschiedliche Werte zurück, ein Feld nicht. DateTime.Now ist ein Beispiel dafür. *Properties haben unter Umständen sichtbare Nebenwirkungen, der Feldzugriff nie. Der Benutzer eines Typs sollte in der Lage sein, verschiedene Eigenschaften, die in einem Typ definiert sind, in beliebiger Reihenfolge zu ändern, ohne dass sich das Verhalten des Typs durch die andere Reihenfolge ändert. *Ein Property benötigt unter Umständen zusätzlichen Ram oder gibt einen Verweis auf etwas zurück, das nicht Teil des Objektzustands ist. So kann eine Eigenschaft auch Kopien zurückgeben, was oft im Code nicht dokumentiert ist.

In Java gibt es aus gutem Grund keine Properties.

Ich persönlich sehe Properties als legitimes Werkzeug, aber man sollte sich vor Augen halten das Properties keine echten Vorteile bieten, bis auf die vereinfachte Syntax.

Und diese bringt durch die Uneindeutigkeit einige Probleme mit sich.

Ich werde in Zukunft wohl deutlich sparsamer mit ihnen umgehen und im Zweifelsfall "richtige" Methode implementieren. 😭

Erstellt vor 14 Jahren

@gfoidl:
Ich habe keine Ahnung, wovon du hier sprichst, aber das hat mit meinen Worten mal wieder NULL zu tun! Und langsam nervt es mich ehrlich gesagt deine Belehrungen zu lesen, wenn du selbst derjenige bist, der hier Bahnhof versteht. 😭

Weder habe ich irgendetwas in Bezug auf Debugger geschrieben, noch ist deine Aussage über Jeffrey Richter korrekt. Der von mir verlinkte Blog hat mit Jeffrey Richter nichts zu tun. Jeffrey Richter ist ein langjähriger .NET-Experte und in seinem Buch "Microsoft .NET Framework - Expertenwissen zur CLR und .NET" geht dieser ausführlich auf Properties und ihre Nachteile ein. Und warum er diese ablehnt.

Der oben verlinkte Blog enthält eine wesentliche Zeile, die mir wichtig war und weshalb ich die Quelle verlinkt habe.

But there are no hard and fast rules and in most cases you shouldn’t have to worry about this, just let the compilers do their thing and certainly don’t try to out guess them. If you do want to see what your code looks like you’ll have to attach the debugger.

Das dort der Debugger aktiv war, das habe ich selbst gelesen. Das musst du mir hier nicht erklären.

In deinem Test-Beispiel kannst du RCE erreichen indem folgendes geschrieben wird:

  
double[] array = testTime2.Array;  
for (int i = 0; i < array.Length; ++i)  
{  
    //  
}  
  

Dadurch wird die Array-Referenz in den lokalen Stack der Methode geholt und der JITer kann die RCE durchführen. Aber das hättest du auch über die (Foren-) Suche, auf die du hingewiesen wurdest, finden können.

Das ist schön, mir aber auch schon bekannt und es ändert auch nichts an den gemessenen Zeiten. Time2 bleibt weiterhin langsamer als Time1, natürlich mit Optimierung im Release Mode!

Erst wenn sämtliche direkten Property-Aufrufe entfernt werden, bekomme ich identische Laufzeiten und dann kann ich auch gleich direkt Arrays verwenden, weil dann brauche ich keine Properties.

for (int i = 0; i < array.Length; i++) {
    array[i] = i;
    i = (int)array[i];
}

Bitte etwas mehr Eigeninitiave und genau lesen was wo steht, sonst drehen wir uns hier im Kreis und das bringt niemanden etwas.

Der ist gut! Mir mangelnde Eigeninitiative vorwerfen, das hatte ich schon lange nicht mehr. Die treffenden Links und Quellcodes haben sich wohl selbst gefunden und geschrieben?

Hast du auch ohne Debugger gemessen?
Im Release Build?
Außerdem ist es keine gute Idee, nur eine Messung durchzuführen - führe lieber in einer Schleife ein paar tausend aus nimm dann die besten.

Natürlich im Release-Build. Es werden in der Schleife rund 10000000 Iterationen durchgeführt. Das reicht allemal.

Zumal mir meine Vermutung eindrucksvoll bestätigt wird. Wenn etwas geht wie eine Ente, Quakt wie eine Ente, dann ist P hoch, das es eine Ente ist.

Erstellt vor 14 Jahren

Hier auch ein kleiner Blogartikel zu Properties.

C# Inline Methods and Optimization

Jetzt weiß ich auch warum Jeffrey Richter Properties nicht mag und in seinem Buch von ihnen abrät.

Man geht sehr schnell viel zu leichtfertig mit ihnen um.

Erstellt vor 14 Jahren

Im Profiler wurde mir nun relativ schnell klar das die verwendete Matrixklasse unzufriedenstellende Resultate liefert.

Eigentlich wollte ich das schon vorher im Profiler testen, habe es aber bisher aufgeschoben.

Hatte mich damals entschieden die Math.NET Library für diverse Matrizenrechnungen zu verwenden. Man muss das Rad ja nicht vollständig neu erfinden.

Nun zeigte sich aber das die Multiplikation, sowie die Skalarmultiplikation von Vektoren enorm viel Zeit beansprucht. Obwohl ich den meisten Overhead aus der Library entfernt habe, ist die Klasse dort immer noch ineffizient.

Ich habe nun die Math.NET interne Multiplikation durch den Strassen-Algorithmus ersetzt, der bei meinen großen Matrizen deutliche Vorteile bringt.

Funzt wunderbar und hat die Performance gleich mal um rund 20 % erhöht. 👍

Den Performanceinbruch führe ich hauptsächlich auf die Properties zurück. Obwohl ich die List durch ein Array ersetzt habe und direkt die Länge abfrage, ist die Performance schlecht geblieben.

Liegt also tatsächlich nur teilweise am Range Check, sondern vielmehr an den Property-Zugriffen. Mit inlinen scheint da nicht viel zu laufen.

Hier ein kleines Testprogramm:

namespace PropertiesPerformanceTest
{
    class TestTime1
    {
        public TestTime1() 
        { 
        }

        public double[] arr = new double[10000000];
    }

    class TestTime2
    {
        public TestTime2() 
        { 
        }

        public double[] Array 
        {
            get { return arr; }
        }

        public int getLength
        {
            get { return arr.Length; }
        }

        private double[] arr = new double[10000000];
    }

    class Program
    {
        static void Main(string[] args)
        {
            try {
                TestTime1 time1 = new TestTime1();
                TestTime2 time2 = new TestTime2();
                Stopwatch watch1 = new Stopwatch();
                Stopwatch watch2 = new Stopwatch();
                watch1.Start();
                for (int i = 0; i < time1.arr.Length; i++) {
                    time1.arr[i] = i;
                    i = (int)time1.arr[i];
                }
                watch1.Stop();
                watch2.Start();
                for (int i = 0; i < time2.getLength; i++) {  // little bit faster with time1.arr.Length
                    time2.Array[i] = i;
                    i = (int)time2.Array[i];
                }
                watch2.Stop();
                Console.WriteLine("Time for 1={0} and 2={1}", watch1.ElapsedMilliseconds, watch2.ElapsedMilliseconds);

            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
            }
            Console.In.ReadLine();
        }
    }
}
Erstellt vor 14 Jahren

Bin schon dabei mit SlimTune Mir die Profilergebnisse im Detail anzusehen. Werde berichten.

Erstellt vor 14 Jahren

Wie soll ich sonst die Arraylänge testen, wenn Count ein Property von IList ist?

Erstellt vor 14 Jahren

Ja, das tausche ich bereits aus, nämlich mit:

int count = myObject.Count;

for (int j = 0; j < count; j++) {
   // ...

Ich werde berichten, ob das Besserung gebracht hat.

Wollte nur wissen, ob das auch beim Indexer passiert...

Danke!

Erstellt vor 14 Jahren

Hallo gfoidl!

Ok, habe mir mal ein wenig die Microsoft Seite angesehen.
Writing High-Performance Managed Applications : A Primer

Da steht auch der Punkt über die Range Check Elimination.

Ich bin mir nur nicht sich sicher wo genau er das durchführen könnte? Beim myObject.Count?

Oder wenn auf das Objekt über den Index zugegriffen wird?

public MyObject this[int index]
{
    get { return _myList[index]; }
}

Gruß,
Stefan