Wie viel wurde gesplittet?

  • Allgemein

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von sonne75.

    Wie viel wurde gesplittet?

    Hi,

    ich habe da eine kleine Frage zum Splitten. Ich möchte nämlich herausfinden, wie viel gesplittet wurde.

    VB.NET-Quellcode

    1. Split("Ich.Du.Er.Sie.Es", ".")


    Jetzt soll in einer MessageBox eine 5 stehen, weil 5 Wörter herausgesplittet wurde. Wie macht man das?
    @SpaceyX: Nur Count ist wesentlich unperformanter. Siehe Absatz nach zweitem Code
    Array.Length gibt direkt die Länge des Arrays zurück. Count ist genaugenommen IEnumerable(Of T).Count(Of T)() und das zählt buchstäblich, wie viele Elemente drin sind.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Niko Ortner: War nur der Vollständigkeit halber.

    Die Extension prüft m. W. n. nicht auf IList, sondern auf ICollection. Es wird, wie @Artentus: sagt, im Grunde .Length zurückgegeben.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @Artentus: Oh, hab gerade nachgesehen. Du hast recht. Da wird zuerst auf ICollection(Of T) und auf ICollection geprüft.
    Wobei immer noch ein Methodenaufruf, ein isinst und ein Methodenaufruf über das Interface gegenüber nur einem Methodenaufruf an eine CIL-Methode stehen.
    Die Length-Property zu verwenden sollte immer noch wesentlich schneller sein.

    Ein Test:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim Temp = Enumerable.Range(0, 100000).ToArray
    2. Dim Value As Integer
    3. Dim SWCount As New Stopwatch
    4. SWCount.Start()
    5. For i = 0 To 1000000
    6. Value = Temp.Count()
    7. Next
    8. SWCount.Stop()
    9. Dim SWLength As New Stopwatch
    10. SWLength.Start()
    11. For i = 0 To 1000000
    12. Value = Temp.Length
    13. Next
    14. SWLength.Stop()
    15. Me.Text = "Count: " & SWCount.ElapsedTicks.ToString & " Length: " & SWLength.ElapsedTicks.ToString

    Ergibt: Count: 125600 Length: 5244
    Und damit wir sicher sein können, dass die Reihenfolge der Tests keine Rolle spielt hab ich's mal umgedreht (Zuerst Length, dann Count): Count: 126403 Length: 5228

    Und ja, da lass ich mal wieder den Perfektionisten raushängen :D

    Edit aus der Zukunft:
    T().Length wird nicht mal als Aufruf an den Getter kompiliert, sondern tatsächlich werden daraus diesr OpCode:
    ldlen, und, wenn nötig z.B. conv.ovf.i4.
    ldlen legt einen native int auf den Stapel und der wird dann z.B. in einen Int32 konvertiert.
    Das ist noch mal schneller als ein Methodenaufruf.
    Also wenn man kann, bei Arrays immer .Length verwenden, und nicht .Count.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Niko Ortner“ ()

    Hi
    ich finde, dass das von der Abstraktion her ein absolutes Unding ist, daher nutze ich das nicht. Man kann in einer unendlichen Menge an Möglichkeiten einfach keinen Fall herauspicken und fragen, ob genau dieser Fall zutrifft, das ist aus Sicht von Abstraktion einfach absolut hässlich. Wenn ich in meiner eigenen Klasse IEnumerable implementiere und eine Count-Property anlege, kann ich den IEnumerable(Of T)-Extensions ja auch nicht sagen, dass sie gefälligst meine Count-Property zu nehmen haben - genauso wenig kann ich mich einer Art "statische Vererbung" zunutze machen, denn so etwas gibt es nur indirekt über Attribute.
    Was dasteht, ist, zähle, wie viele Elemente im IEnumerable sind und gehe dabei - wie einzig möglich auf der Schnittstelle IEnumerable - jedes Element durch.

    Gruß
    ~blaze~
    @~blaze~: Ja, ich finde, die IEnumerable-Geschichte ist einer der ganz wenigen Punkte im .Net-Framework der nicht sauber durchdacht ist.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Niko Ortner: Durchdacht schon, aber so umgesetzt, dass es performanter ist. Ich hätte ja "statische Vererbung" mit eingebaut, sodass man die Extensions für Typen überschreiben kann, aber das ist in der CLI nicht so vorgesehen, afaik. Ich denke halt, dass die intern (z.B. OrderBy) Listen verwenden, wo dann Count performanter wäre (aber wer würde bei OrderBy schon sowas machen wollen?!) und für custom types gibt's dann halt die Möglichkeit, ICollection zu implementieren. Ist aber mMn. trotzdem von der Abstraktion her extrem hässlich. Naja, kann man nichts machen. Entweder in der Architektur der CLI so beabsichtigt oder nicht mit eingeplant gewesen.
    @sonne75: Length für Arrays, die Count-Eigenschaft für ICollection(Of T) und ICollection und die Count-Funktion für IEnumerable(Of T), das nicht ICollection(Of T) ist.

    Gruß
    ~blaze~
    @~blaze~
    Es ergibt insofern schon Sinn, denn ICollection ist ja eine Erweiterung von IEnumerable, und da es eben wie schon gesagt nicht möglich ist, eine Extension zu überschreiben, ist dies quasi die einzige Möglichkeit.
    Statische Vererbung gibt es in diesem Sinne ja auch gar nicht. Vererbung bedeutet ja eigentlich, dass der ganze Polymorphie-Kram dabei ist, eine statische Vererbung wäre aber nicht im mindesten polymorphisch, da ja gar keine Objekte vorliegen. Statische Vererbung wäre daher eigentlich nur ein Zwang, dass ein statischer Member in der Klasse vorkommen muss (im Falle, dass der Member abstract ist), bzw. dass man statische Member der Basisklasse aus der abgeleiteten Klasse ausrufen kann (falls der Member nicht abstract ist). Virtual ist also überhaupt nicht möglich und abstract wäre auch nicht im Sinne von Polymorphie, sondern im Sinne eines Zwanges, einen statischen Member implementieren zu müssen.
    Problem an sich ist halt die CLR, weil es da eben Mehrfachvererbung nur mit Interfaces gibt, wodurch Wxtensions überhaupt erst nötig werden. In C++ wäre es absolut kein Problem sowas zu implementieren, aber ich bin mir sicher, die Entwickler bei Microsoft werden sich schon was dabei gedacht haben, keine Mehrfachvererbung zuzulassen.
    Allerdings muss ich auch sagen, Extensions könnten mehr sein, als sie jetzt sind. Warum gehen z.B. keine Extension-Operatoren? Die wären imo ne gute Ergänzung und würden auch dem Extension-Prinzip in keinster Weise widersprechen.
    Statische Mitglieder ähneln häufig eher Singletons, daher würde es schon Sinn machen und somit eigentlich auch die Vererbung innerhalb solcher Singletons. Es würde entsprechend auch Sinn machen, wenn man "statische Extensions" einbauen könnte oder Vererbung innerhalb von Extensions möglich wäre (bspw. per kompletten Typen, die eine Extension darstellen). Ohne die Extension von statischen Methoden widerspricht's btw. auch den Operatoren.
    In C++ ist halt eine Schnittstelle an sich auch nicht als solche markiert.
    Ich finde es dennoch hässlich, wie es gelöst wurde. Ich würde es als einen der relativ wenigen Schönheitsfehler der CLR sehen und ich bleibe trotzdem dabei, dass es ein Schönheitsfehler ist ;).

    Gruß
    ~blaze~

    ~blaze~ schrieb:

    Statische Mitglieder ähneln häufig eher Singletons, daher würde es schon Sinn machen und somit eigentlich auch die Vererbung innerhalb solcher Singletons. Es würde entsprechend auch Sinn machen, wenn man "statische Extensions" einbauen könnte oder Vererbung innerhalb von Extensions möglich wäre (bspw. per kompletten Typen, die eine Extension darstellen).
    Nur, dass dann wieder niemand außer dir durchblicken würde. :D
    Zeig mal, wie du Extensions umsetzen würdest, das interessiert mich jetzt.

    C-Quellcode

    1. public singleton SWeirdSingleton
    2. {
    3. //statisches interface
    4. TypeConverter GetTypeConverter();
    5. new(string someConstructorParameter);
    6. }
    7. public class SomeWeirdType :: SWeirdSingleton
    8. {
    9. public virtual static TypeConverter GetTypeConverter()
    10. {
    11. //or as singleton!
    12. return new SomeWeirdTypeTypeConverter();
    13. }
    14. public SomeWeirdType(string someConstructorParameter)
    15. {
    16. }
    17. //...
    18. }
    19. public extension MyType<SomeWeirdType>
    20. {
    21. //überschreibbare Extension
    22. public virtual void DoSomeExtremelyCrazyStuff()
    23. {
    24. MessageBox.Show(((SWeirdSingleton)SomeWeirdType).GetTypeConverter().ConvertToString(this));
    25. }
    26. public static void Bla()
    27. {
    28. }
    29. }


    Vererbung dieser Typen wird über die Konstruktion im statischen Konstruktor umgesetzt. Der wird von meinem theoretischen JITC aufgerufen, sobald das singleton konstruiert wird, bzw. statische Mitglieder aufgerufen werden. Das Singleton entspricht hierbei eben der Maske, der Offset des jeweiligen Singletons in den statischen Methoden wird dazu verwendet, die Methoden den Interfaces zuzuordnen (somit ergibt sich eben für Methode x des Interfaces und Offset des Singletons y eben y + x * n, wenn n die Breite des Methodenzeigers ist). Die Zuordnung erfolgt indirekt. Vererbung wird über die Übernahme der Methodentabelle und Ersetzung der Einträge ermöglicht.
    MyType wäre als Typ einfach ein Typ, der die Instanz in einer Property behält und vererbbar ist (reicht den Konstruktor nach unten durch oder führt auch Typeinschränkungen durch. Der Typ von this entspricht dem generischen Argument.

    Gruß
    ~blaze~