Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Codeoptimierungsanregungen gesucht


bLuTm8 - Mi 16.02.05 21:21
Titel: Codeoptimierungsanregungen gesucht
hallo delphi freunde :)

viele von euch kennen bestimmt das phänomen, wenn man wochenlang an einem programm codet,
das man nach einiger zeit den blick für das wesentliche/naheliegende aus den augen verliert
und um letztlich den code irgendwie lauffähig zu bekommen dann recht "umständliche" routinen
baut.

ich sitze zur zeit an einem chatclienten, der soweit hervorragend arbeitet. allerdings ist
der smilie-parser-code der vom chatserver empfangenen nachrichten etwas "unglücklich"
(viel zuviele if-verzweigungen)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
 // result enthält den index der pics in einer imagelist oder 0 für false
function IsSmilie2(code: ShortString): Byte;
begin
  code := UpperCase(code);
  if      code = ':)' then result := 1
  else if code = ':(' then result := 2
  else if code = ';)' then result := 3
...
  else if code = 'X(' then result := 14
  else if code = '=;' then result := 27
  else result := 0;
end;

function IsSmilie3(code: ShortString): Byte;
begin
  code := UpperCase(code);
  if      code = ';;)' then result := 5
  else if code = ':-/' then result := 7
  else if code = ':">' then result := 9
...
  else result := 0;
end;

'IsSmilie4' ist identisch (halt für 4bytes)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
procedure TChatForm.Display_Message(Nick, Msg: string; NickStyle, MsgStyle: Byte);
var
  i: Integer;
  idx: byte;
  sLeft: string;
begin
  RVChat.AddFromNewLine(Nick+#32, NickStyle);
  Msg    := Trim(Msg);
  sLeft  := '';
  i      := 1;
  while i < Length(Msg) do
    begin
      if IsSmilie4(copy(Msg,i,4)) <> 0 then
        begin
          idx := IsSmilie4(copy(Msg,i,4));
          // alles vorhergehende anzeigen
          RvChat.Add(copy(sleft,1,length(sLeft)-1), MsgStyle);
          sLeft  := '';
          // print smilie
          RVChat.AddBullet(idx-1, SmilieImageList, false);
          // den reststring holen
          inc(i,4);
          if Trim(copy(Msg,i,Length(Msg))) = '' then Break;
        end
      else if IsSmilie3(copy(Msg,i,3)) <> 0 then
        begin
          idx := IsSmilie3(copy(Msg,i,3));
          RvChat.Add(copy(sleft,1,length(sLeft)-1), MsgStyle);
          sLeft  := '';
          RVChat.AddBullet(idx-1, SmilieImageList, false);
          inc(i,3);
          if Trim(copy(Msg,i,Length(Msg))) = '' then Break;
        end
      else if IsSmilie2(copy(Msg,i,2)) <> 0 then
        begin
          idx := IsSmilie2(copy(Msg,i,2));
          RvChat.Add(copy(sleft,1,length(sLeft)-1), MsgStyle);
          sLeft  := '';
          RVChat.AddBullet(idx-1, SmilieImageList, false);
          inc(i,2);
          if Trim(copy(Msg,i,Length(Msg))) = '' then Break;
        end
      else // kein smilie
        begin
          sLeft := sLeft + copy(Msg,i,1);
          inc(i);
        end;
    end;
  { Rest anzeigen }
  RVChat.Add(sleft+copy(Msg,i,1), MsgStyle);
  RVChat.FormatTail;
  RVChat.Refresh;
end;



TRVChatForm ist eine auf TRichView basierende komponente, die wiederum auf
richedit (ohne editierfunktion) basiert.

Ich würde mich über ein paar anregungen freuen ;)

grüssle bluti

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconTino: Topic aus Sonstiges verschoben am Mo 21.02.2005 um 13:26


I.MacLeod - Mi 16.02.05 21:46

Eine einfache Lösung:

erstell eine TStringList mit dem Inhalt:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
:)
:(
;)
...
;;)
...
:-/
...
:">
...
...


Und dann holst du dir den Index mit StringList.IndexOf(code). Wenn das Ergebnis -1 ist ists kein Smiley.


bLuTm8 - Mi 16.02.05 22:05

danke dir,

das war auch mein erster ansatz (zwar keine stringliste, sondern ein array aus konstanten), aber egal ob statisch oder dynamisch,
die sache hat einen haken:

einige smilies haben ähnliche codes (zb: ": )" und ": ) )"), so das ich auch hier wieder eine fallentscheidung anhand der länge des codes treffen muss (welchen der beiden indexe liefert mir delphi beim stringsuchen ": )" in obigem beispiel ?) ...

ok, gehen wir davon aus, das ich drei arrays bzw tstrings erstelle.
dann tut sich das nächste problem auf: die indexe der listen/arrays sind nicht mehr mit denen in der imagelist "kompatibel", so das erneut zusatzcode anfällt.

... ziemlich verzwickt, diese ansich eigentliche einfache aufgabe


BenBE - Mi 16.02.05 22:57

IndexOf sucht immer nach exakten Übereinstimmungen.

BtwBTW: Wenn du mehrere Smileys hast, die den gleichen Code zurückliefern sollen, kannst Du Byte für Byte als HEX-Zahl kodieren (aus "." wird dann "2E" und sowas) dann kannst Du mit Result := IntToStrDef(SL.Values[HexSmileyName], -1); deinen Smiley in einen Index übersetzen, wenn deine Liste z.B. so hier aussieht:


Quelltext
1:
2:
2E=0
2F=1

(2E=.; 2F=:)

Für mehrbyte-Smileys einfach die Bytes hintereinanderfügen.
2F2E --> :.


bLuTm8 - So 20.02.05 01:33

vielen dank :)

das war genau die richtung bzw eingebung, die mir partout nicht kommen wollte....

ich experimentiere damit momentan ein wenig rum und hab auch noch ein paar andere projekte parallel,
sodass ich erst jetzt zeit zum antworten fand ;)