Autor |
Beitrag |
GiuStyler
Beiträge: 65
Erhaltene Danke: 1
Win 8.1
Delphi XE6
|
Verfasst: Mi 22.06.16 08:50
Hallo Community,
ich habe ein kleines Problem. Ich habe folgendes Code was auch funktioniert. Aber sicherlich geht es auch einfacher. Nur ich habe da wieder meine Problemchen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| if Pos('Fett', ls_wert) > 0 then l_cell.Style.Font.Style := [fsBold]; if Pos('Kursiv', ls_wert) > 0 then l_cell.Style.Font.Style := [fsItalic]; if Pos('FettKursiv', ls_wert) > 0 then l_cell.Style.Font.Style := [fsBold] + [fsItalic]; if Pos('Unterstrichen', ls_wert) > 0 then l_cell.Style.Font.Style := [fsUnderline]; if Pos('Durchgestrichen', ls_wert) > 0 then l_cell.Style.Font.Style := [fsStrikeout]; if Pos('UnterstrichenDurchgestrichen', ls_wert) > 0 then l_cell.Style.Font.Style := [fsUnderline] + [fsStrikeout]; |
Dieser Code dient dazu, um zu überprüfen ob das Wort (Fett, Kursiv, FettKuriv etc.) gibt ja verschiedene Möglichkeiten wie das Wort sein kann. Dieser soll dann in die DB eingetragen werden. Wie kriege ich es nun hin das ich anstatt alles einzeln abzufragen (jede Möglichkeit) es so machen kann das ich sagen, wenn das Wort (Fett ist) dann mach [fsBold] wenn es (FettKursivUnterstrichen ist) dann zeige das mir an in der DB.
Habe mir überlegt es mit Case zu machen, aber auch da denke ich das der Code zu viel würde.
|
|
OlafSt
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Mi 22.06.16 09:35
Zunächst einmal: Die Methode, wie du sie gewählt hast, führt fast unweigerlich zu solchen If-Arien. Außerdem ist dieses Text-Parsen sehr zeitaufwändig. Aber das wirst du von allein merken, wenn diese Abfrageroutine mal einen größeren Text zu schlucken bekommt...
Wie dem auch sei. Drei Dinge sollten dir deutlich weiterhelfen:
1. Der Fontstyle ist eine Menge. Darum auch das Geraffel mit den eckigen Klammern. Wenn du dich mit Mengen beschäftigst, wird dir auffallen, das man Werte dazuaddieren oder abziehen kann. Wie bei nem Integer:
Delphi-Quelltext 1:
| Font.Style:=Font.Style + [fsBold]; |
2. Vergleiche mit Zeichenketten, die von Menschen eigegeben oder modifiziert werden, haben immer das Problem der Vertipperei. Dagegen bist du machtlos. Wer es nicht packt, "Fett" richtig zu schreiben, muß eben mit normalem Text bestraft werden.
Ansonsten mußt du zusehen, das all diese Texte in eine Art generalisiertes Format gebracht werden, um die Anzahl Vergleiche zu reduzieren. Es wäre Wahnsinn, "Fett", "FEtt", "FETt", "FETT", "fEtt" etcpp... all diese kaputten (und möglichen !) Schreibweisen abzutesten.
Um das zu bewerkstelligen, wandelt man die Zeichenkette üblicherweise in LCase oder UCase um. Damit eliminierst du alle oben genannten Schreibweisen auf "fett" (im Falle von LCase) oder "FETT" (im Falle von UCase). Und deine Anzahl Tests reduziert sich auf genau 1.
3. Wenn du nun beides in eine Schüssel kippst, das ganze mit der Funktionsweise von Pos würzt, kräftig umrührst und eine homogene Suppe draus machst, wird dir sicher eine äußerst effiziente Lösung für das Problem einfallen.
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 22.06.16 11:05
OlafSt hat folgendes geschrieben : | Um das zu bewerkstelligen, wandelt man die Zeichenkette üblicherweise in LCase oder UCase um. |
Üblich ist eher AnsiContainsText aus der Unit System.StrUtils zu verwenden.
AnsiContainsStr schaut, ob der String in exakt der Schreibweise in dem anderen vorkommt, AnsiContainsText, ob er in egal welcher Schreibweise vorkommt.
|
|
OlafSt
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Do 23.06.16 10:42
...und AnsiContainsText geht denselben Weg - eben nach UCase zu wandeln und dann zu prüfen.
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 23.06.16 11:30
Es gibt aber durchaus auch andere Implementierungsversuche um das zu beschleunigen. Deshalb sollte man die entsprechenden Funktionen der RTL benutzen, falls diese optimiert werden.
Zudem ist AnsiContainsText kürzer und sprechender als das selbst jedesmal zu machen.
|
|
jasocul
Beiträge: 6388
Erhaltene Danke: 146
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 24.06.16 07:31
jaenicke hat folgendes geschrieben : | Zudem ist AnsiContainsText kürzer und sprechender als das selbst jedesmal zu machen. |
Ist das wirklich sprechender? Ich müsste vermutlich oft überlegen, ob AnsiContainsStr oder AnsiContainsText die Schreibweise berücksichtigt. Für mich wäre es klarer, wenn es nur eine Methode gibt, mit Parameter. Wie z.B. bei StringReplace. Ist aber vielleicht nur Geschmackssacke.
Und ob der Source mal optimiert wird, möchte ich bezweifeln. Aber das ist wie ein ganz anderes Thema.
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 24.06.16 11:41
|
|
doublecross
Beiträge: 149
Erhaltene Danke: 27
Windows 7
C#; Visual Studio 2015
|
Verfasst: Fr 24.06.16 17:47
jaenicke hat folgendes geschrieben : | Es gibt aber durchaus auch andere Implementierungsversuche um das zu beschleunigen. Deshalb sollte man die entsprechenden Funktionen der RTL benutzen, falls diese optimiert werden. |
Dennoch sollte man deshalb eigene Optimierungen nicht hinten anstellen. Wenn AnsiContainsText bei jedem Aufruf ein UCase macht ist dies sicherlich teurer, als wenn ich einmal am Anfang meiner Funktion einen durchführe und alle meine Vergleiche auf der Variable durchführe in der ich das Ergebnis gespeichert habe. Solle das zu wenig sprechend sein, kann man es ja per Kommentar erklären .
|
|
GuaAck
Beiträge: 378
Erhaltene Danke: 32
Windows 8.1
Delphi 10.4 Comm. Edition
|
Verfasst: Sa 25.06.16 00:10
Interessante Diskussion: Laufzeit <---> Lesbare Source
Laufzeit: Ich habe für solche Fragen einen Profiler (ProDelphi) (der baut z. B. zu Beginn und zum Ende einer jeden Prozedur im Quellprogramm eine Zeile Assembler-Code ein, die die Zeit in einem eigenen Speicherbereich summiert. In der Auswertung kann man bestens sehen, welcher Teil eines Programms der Zeitfresser ist). Ich habe da schon überraschende Laufzeit-Erkenntnisse gewonnen.
Es gibt wohl eine Freeware oder Demo, oder poste mal jemand einen fertigen Quellcode (ZIP), dann messe ich mal. (Delphi 7, Win 8.1)
Viele Grüße GuaAck
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 25.06.16 09:41
Da das nicht das Thema war nur kurz:
Als Profiler würde ich eher AQTime nehmen. Der zeigt zeilenweise an statt prozedurweise.
Jedenfalls steht für mich die Lesbarkeit an erster Stelle und optimiert wird wo es wirklich für die Performance nötig ist.
|
|
|