Et pour clore la discussion, je viens de faire quelques essais, et mon idée d'un CaseOf optimisé par une méthode inspirée du tri rapide ne tient pas la route. Tant pis.
La méthode du tableau de conversion reste la plus rapide. J'en ai fait une version assembleur, mais elle n'est pas beaucoup plus rapide que la version Pascal !
Edit : le MOV ECX,EDX n'est pas inutile, il est là pour pouvoir éventuellement utiliser l'instruction LOOP ; il paraîtrait que la performance gagnée/perdue par l'usage de LOOP dépend du type de processeur...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
54 // Constante à utiliser pour conversion en majuscules non accentuées. // Pour une simple suppression des accents, utiliser l'autre constante, // celle qui contient des minuscules. var CharTable : array[Char] of Char = #0#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 + ' !"#$%&''()*+,-./0123456789:;<=>?' + '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' + '`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~'#127 + ''#129' S'#141'Z'#143#144'S'#157'ZY' + #160'¡¢£¤¥¦§¨©ª«¬*®¯°±²³´µ¶·¸¹º»¼½¾¿' + 'AAAAAAÆCEEEEIIIIDNOOOOO×OUUUUYÞß' + 'AAAAAAÆCEEEEIIIIDNOOOOO÷OUUUUYÞY'; function CJ8Buff(S:PAnsiChar;Len:Integer):PAnsiChar;register; asm PUSH ESI // Sauvegarde ESI par nécesssité technique PUSH EDI // Sauvegarde EDI par nécesssité technique PUSH EBX // Sauvegarde EBX par nécesssité technique PUSH EAX // Sauvegarde l'adresse de la chaîne pour retour CLD XOR EBX,EBX // EBX := 0 CMP EDX,EBX // Len <= 0 ? JLE @Out // Si oui, sauter MOV ESI,EAX // Adresse de la chaîne dans ESI MOV EDI,EAX // Même adresse dans EDI MOV ECX,EDX // Longueur dans ECX LEA EBX,CharTable // Adresse du tableau dans EBX @Loop: LODSB // AL <- [ESI] ; Inc(ESI) XLAT // AL <- [EBX + AL] STOSB // [EDI] <- AL ; Inc(EDI) DEC ECX // On décrémente le compteur JNE @Loop // si pas fini, boucle @Out: POP EAX // renvoie dans Result l'adresse de la chaîne POP EBX POP EDI POP ESI end; function CJ8(const S:string):string; var Len: Integer; begin Len := Length(S); SetString(Result, PChar(S), Len); if Len > 0 then CJ8Buff(Pointer(Result), Len); end;
Edit 2 : S'il y a si peu de gain de performance, c'est sans doute parce que cette routine doit être très proche de la routine CharUpperBuff de Windows, utilisée par Delphi...
Partager