Wie würdet ihr einen Editor schreiben? Jede Zeile als ein Objekt?



  • Ich habe mir mal das überlegt, wie man einen Text in einem Editor am besten verwaltet.

    Ein Stream ist ja eigentlich recht unhandlich, wenn man Wörter farbig hervorheben möchte oder Zeilen umkopieren möchte.

    Aber als Objekte geht das doch sicher gut.
    Die eigentliche Frage ist halt, wie performant ist das?


  • Mod

    Du machst die Performancesorgen bei einem Editor? 😮

    Denk dir lieber ein Konzept aus, mit dem du deinem Editor leicht geile Features hinzufügen kannst. Schnell genug ist das dann schon von alleine.



  • Das ist von einem der Entwicler des KDE-Editors. Fand ich dazu sehr schön.

    http://dhaumann.blogspot.com/2010/02/kate-internals-text-bufferu.html



  • SeppJ schrieb:

    Du machst die Performancesorgen bei einem Editor? 😮

    Ich würde mir ziemlich viele Gedanken um die Performance machen. Ein Editor ist nicht ohne wenn er mit viel Text umgehen können muss.



  • SeppJ schrieb:

    Du machst die Performancesorgen bei einem Editor? 😮

    Denk dir lieber ein Konzept aus, mit dem du deinem Editor leicht geile Features hinzufügen kannst. Schnell genug ist das dann schon von alleine.

    Deswegen habe ich mir gedacht, daß ich jede Zeile oder nach reifer Überlegung besser jedes Wort in ein eigenes Objekt packe, denn dann kann ich jedes Wort einzeln z.B. eine Vorder- oder Hintergrundfarbe zuweisen, oder unterstreichen, oder fett machen usw..
    Einzelne oder mehrere Leerzeichen würde ich ebenfalls als eigene Wörter zählen.
    Für Sonderzeichen gilt das gleiche.
    Und normale Wörter würden aus Buchstaben oder Zahlen bestehen.

    Beispiel als Pseudocode:

    class word{
      string word;
      int vgcolor;
      int bgcolor;
      int *previtem;
      int *nextitem;
      bool underlined;
      bool fat;
    }
    

    Ne extra Schriftart brauche ich allerdings nicht, denn ich will ja keine Textverarbeitung schreiben.
    Underlined und fat kann ich allerdings zum Markieren bei der Darstellung nutzen, in die Textdatei gespeichert wird das natürlich nicht.

    Ich habe mir das mal als Liste vorgestellt.
    Das Speichern in einem Baum wäre auch ne Möglichkeit.
    Ich könnte zwecks besserer Performance mehrere Wörterobjekte auch in Blöcke zusammenfassen und dann für jeden Block einen Baum anlegen.

    Ist die Idee gut und ist das noch performant?

    Der Satz:

    "Ist die       Idee gut?"
    

    Würde also ohne die Gänsefüßchen 8 Objekte ergeben.
    Die Leerzeichen kann ich leider nicht mit den Wörtern zusammenfassen, denn vielleicht will ich den Hintergrund eines Wortes ändern und dann wäre es blöd, wenn der Hintergrund für das Leerzeichen sich ebenfalls verändern würde.



  • Jetzt fällt mir gerade noch ein, die Sonderzeichen darf ich nicht zusammenfassen, sondern die müssen alle als einzelne Wortobjekte betrachtet werden, denn vielleicht habe ich mal einen geschachtelten Text bei denen ich die Klammern hervorheben will.

    Bsp:

    ((1*3) / (3/2))
    

    Wenn ich die beiden äußeren Klammern rot machen will, dann kann ich die natürlich nicht mit der danebenstehenden Klammer einfärben.



  • Ich würde mir ziemlich viele Gedanken um die Performance machen. Ein Editor ist nicht ohne wenn er mit viel Text umgehen können muss.

    Kann ich bestätigen. gedit ist das Gegenbeispiel zu "wird schon schnell genug sein".
    Bis eine größere Logdatei geöffnet ist und dann auch alle Zeilen im Editor aufgetaucht sind können schon mal einige Minuten vergehen.
    Zum Vergleich: Geany, Scite und Emacs schaffen das in <=1 sec.
    Vom RAM-Verbrauch redet man lieber erst gar nicht (323 MB für eine 21 MB-Textdatei).
    Das kann nur noch von kate mit 550 MB getoppt werden (dafür dauert das Laden auch nur zwei Sekunden).

    Aber die Repräsentierung von jeder Zeile als eigenes Objekt ist sicher nicht schuld daran.

    Kurzer Test in C++ mit einer 484 MB-Logdatei (7.6 Millionen Zeilen):
    Einlesen als binärer Blob: 0.85s
    Zeilenweises Einlesen in einen vector<string>: 1.6s
    Zeilenweises Einlesen in eine list<string>: 2.0s
    Schreiben als binärer Blob: 1.5s
    Zeilenweises Schreiben aus einem vector<string>: 1.7s
    Zeilenweises Schreiben aus einer list<string>: 2.0s

    Edit: Um Formatierungen pro Zeichen speichern zu können, gäbe es auch noch das da: http://de.wikipedia.org/wiki/Flyweight
    Könnte bei zu sorglosem Umgang allerdings zu Performanzproblemen führen.



  • Athar schrieb:

    Kurzer Test in C++ mit einer 484 MB-Logdatei (7.6 Millionen Zeilen):
    Einlesen als binärer Blob: 0.85s
    Zeilenweises Einlesen in einen vector<string>: 1.6s
    Zeilenweises Einlesen in eine list<string>: 2.0s
    Schreiben als binärer Blob: 1.5s
    Zeilenweises Schreiben aus einem vector<string>: 1.7s
    Zeilenweises Schreiben aus einer list<string>: 2.0s

    Ok, nehmen wir mal an du liest eine Logdatei ein.
    Z.b. die Logs von IPTables Meldungen.

    Und nun möchtest du die jeweiligen Felder wie TCP und UDP Port, Destination und Source IP Adresse usw. einzeln farbig hervorheben, wie machst du das, daß du es als binärer Blob einliest?



  • Ich würde bei meinem Texteditor übrigens nicht das gesamte Dokument auf einmal einlesen, sondern nur den Bereich, der auch dargestellt wird bzw. ein klein bischen mehr, sagen wir mal alle 300 Zeilen.

    Und für die 100 Zeilen vor und hinter den gerade sichtbaren Zeilen würde ich im Hintergrund in so einer Art Triplebuffer laden.



  • Objekteditor schrieb:

    Und nun möchtest du die jeweiligen Felder wie TCP und UDP Port, Destination und Source IP Adresse usw. einzeln farbig hervorheben, wie machst du das, daß du es als binärer Blob einliest?

    Gar nicht, das war nur zum Vergleich gedacht.



  • Athar schrieb:

    Objekteditor schrieb:

    Und nun möchtest du die jeweiligen Felder wie TCP und UDP Port, Destination und Source IP Adresse usw. einzeln farbig hervorheben, wie machst du das, daß du es als binärer Blob einliest?

    Gar nicht, das war nur zum Vergleich gedacht.

    Dann ist der Vergleich aber Praxisfremd, wenn ich beim "als Binärblock einlesen"
    keine Einfärbungen durchführen kann.
    Ich will schon nen Editor bauen, bei dem ich einzelne Wörter einfärben kann.



  • Ja, das ist schon klar. Ich wollte zeigen, dass auch beim Einlesen und Speichern durch ein eigenes Objekt für jede Zeile nicht viel Performanz verloren geht.
    Aber gerade wenn du zeichengenaue/wortgenaue Formatierung brauchst, bleibt dir ohnehin nicht viel anderes übrig.

    Objekteditor schrieb:

    Ich würde bei meinem Texteditor übrigens nicht das gesamte Dokument auf einmal einlesen, sondern nur den Bereich, der auch dargestellt wird bzw. ein klein bischen mehr, sagen wir mal alle 300 Zeilen.

    Und für die 100 Zeilen vor und hinter den gerade sichtbaren Zeilen würde ich im Hintergrund in so einer Art Triplebuffer laden.

    Was machst du, wenn jemand einen ganzen Abschnitt löscht/verändert und dann an eine andere Stelle der Datei springt? Und beim Speichern? Das könnte schnell kompliziert werden.



  • Athar schrieb:

    Was machst du, wenn jemand einen ganzen Abschnitt löscht/verändert und dann an eine andere Stelle der Datei springt? Und beim Speichern? Das könnte schnell kompliziert werden.

    Guter Einwand.

    Falls der Text verändert wird, dann müßte ich diese Bereiche natürlich im Hintergrund merken, also im RAM vorhalten, bis gespeichert wird.

    Anderseits ist so etwas trotzdem sinnvoller, als die gesamte Textdatei im Speicher zu halten, denn was machst du, wenn du nur 4 GB RAM auf dem Rechner hast, deine Textdateie aber > 4 GB groß ist?

    Mir ist das zwar bei einer Textdatei noch nicht passiert, aber sehr wohl bei einem Hex-Editor.
    Und da trennt sich schnell die Spreu vom Weizen, welcher Hex-Editor überhaupt noch für große Dateien in Frage kommt.
    Manche Hex-Editoren konnten die große Datei zwar einlesen, aber beim "Search & Replace" scheiterten sie dann.
    Solche Sachen sollen bei meinem Editor nicht vorkommen.



  • Objekteditor schrieb:

    Deswegen habe ich mir gedacht, daß ich jede Zeile oder nach reifer Überlegung besser jedes Wort in ein eigenes Objekt packe, denn dann kann ich jedes Wort einzeln z.B. eine Vorder- oder Hintergrundfarbe zuweisen, oder unterstreichen, oder fett machen usw..

    Dazu müsstest du erstmal "Wort" definieren. Für Programmiersprachen ist das nicht praktikabel (Kommentare, Strings...).
    Besser sind Klassen wie Cursor und Range. Siehe auch den verlinkten Beitrag zum Kate-Editor.

    Eine Range wäre quasi ein Wort wo aber Anfang und Ende auf beliebige Stellen (Cursor) im Text zeigen. Dann kannst du auch sagen range->set_color().



  • DrGreenthumb schrieb:

    Objekteditor schrieb:

    Deswegen habe ich mir gedacht, daß ich jede Zeile oder nach reifer Überlegung besser jedes Wort in ein eigenes Objekt packe, denn dann kann ich jedes Wort einzeln z.B. eine Vorder- oder Hintergrundfarbe zuweisen, oder unterstreichen, oder fett machen usw..

    Dazu müsstest du erstmal "Wort" definieren.

    Hab ich doch eigentlich oben schon.

    Für Programmiersprachen ist das nicht praktikabel (Kommentare, Strings...).
    Besser sind Klassen wie Cursor und Range. Siehe auch den verlinkten Beitrag zum Kate-Editor.

    Eine Range wäre quasi ein Wort wo aber Anfang und Ende auf beliebige Stellen (Cursor) im Text zeigen. Dann kannst du auch sagen range->set_color().

    Warum wäre das für Quellcode nicht praktikabel?



  • Objekteditor schrieb:

    Einzelne oder mehrere Leerzeichen würde ich ebenfalls als eigene Wörter zählen.
    Für Sonderzeichen gilt das gleiche.
    Und normale Wörter würden aus Buchstaben oder Zahlen bestehen.

    /* Und wenn du jetzt einen String einfärben willst? */

    Da hast du den Anfang und ein Ende. Das ist besser als 1000 Wörter.



  • DrGreenthumb schrieb:

    Objekteditor schrieb:

    Einzelne oder mehrere Leerzeichen würde ich ebenfalls als eigene Wörter zählen.
    Für Sonderzeichen gilt das gleiche.
    Und normale Wörter würden aus Buchstaben oder Zahlen bestehen.

    /* Und wenn du jetzt einen String einfärben willst? */

    Da hast du den Anfang und ein Ende. Das ist besser als 1000 Wörter.

    Das mag für ein Comment so gelten, aber so etwas:

    #include <x.h>
    
    int func(const char *filename)
    {
      int len = 0;
      #ifdef _WIN32
      	file = fopen(filename, "r"); //if win32 - open the filename in current dir
      #else
        if (len==1)
        {
          if ((str[0]=='0') || (str[0]=='N'))
            ret=0;
          else
            ret=1; 
        }
      printf("Blabla = %i\n", i);
      return 0;    
    }
    

    Hat schon viele verschiedene Farben.
    Die den Variablentypen int, const char und den Schlüsselwörtern wie if, else, while use. kann man eine Farbe geben.
    Den Zahlen kann man eine andere Farbe geben, als einem Zeichen '0' oder String im Programm.
    Der Kommentarblock hat ne extra Farbe.
    include und #ifdef und #else hat ne eigene Farbe.
    Man könnte auch %i und \n in der Printfanweisung speziell hervorheben.
    Und wenn man auf die { klickt, dann sollte diese und die untere dazu passende }
    ebenfalls in einer anderen Farbe hervorgehoben werden.

    Macht 6 Farben und alle kommen sehr oft und abwechselnd vor.
    Du bräuchtest also sehr viele indirekten Anfang und Ende Zuweisungen.
    Der Code wird dadurch nicht einfacher, sondern komplexer.
    Denn wenn du z.b. einen String Zeilenweise einliest, dann brauchst du auch z.B. eine dynamische Liste für die vielen Anfänge und Enden einer Einfärbung, sowie der dazu passenden Farbe oder Farbindexnummer.

    Allein für diese Zeile:

    if ((str[0]=='0') || (str[0]=='N'))
    

    Hast du 5 Anfänge und Enden, wobei 4 davon nur für ein einzelnes Zeichen verwendet werden. Nämlich 0, '0', 0 und 'N'.
    Der 5. Bereich wäre für das if.

    PS: Nicht in die Irre führen lassen, das Forum hebt Zahlen hier farblich leider nicht hervor, wäre aber sinnvoll, gute Editoren tun das.



  • Objekteditor schrieb:

    PS: Nicht in die Irre führen lassen, das Forum hebt Zahlen hier farblich leider nicht hervor, wäre aber sinnvoll, gute Editoren tun das.

    #ifdef & Co wird übrigens hier auch nicht speziell hervorgehoben, obwohl es sinnvoll wäre.

    _WIN32 könnte man übrigens ebenfalls noch farblich hervorheben, damit es zusätzlich zur Großschreibung sich auch noch farblich von normalen Variablen abhebt.



  • Athar schrieb:

    Kurzer Test in C++ mit einer 484 MB-Logdatei (7.6 Millionen Zeilen):
    Einlesen als binärer Blob: 0.85s

    Von was für einem Speichermedium wurden die Daten gelesen? Eine normale Festplatte packt keine 500MB pro Sekunde.



  • Ich will schon nen Editor bauen, bei dem ich einzelne Wörter einfärben kann.

    Was, wenn du Zeichenketten suchen moechtest und gefundene Farbig hervorheben moechtest? Ueber mehrere Woerter, oder auch innerhalb. Jedes Wort ein Objekt halte ich fuer schlecht.


Log in to reply