OlafvdSpek schreef op 22 november 2002 @ 20:15:
[...]
Nog steeds relatief duur.
[...]
Ik heb de volgende functie nu herschreven om een 256 byte buffer te gebruiken indien mogelijk, maar dat is nog steeds niet het beste.
Het gaat om functies als:
C++:
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
| string web_encode(const string& v, bool add_br)
{
string r;
int i = 0;
while (i < v.length())
{
char c = v[i++];
switch (c)
{
case '\r':
break;
case '\n':
if (add_br)
r += "<br>";
r += '\n';
break;
case '<':
r += "<";
break;
case '>':
r += ">";
break;
case '&':
r += "&";
break;
case '"':
r += """;
break;
default:
r += c;
}
}
return r;
} |
Dat algoritme is mis. Dit soort conversies wil je inderdaad in een loop doen. Maar hoe lang is die string v? Als die orde-grootte 1K is, dan zou ik in scan 1 via een LUT bepalen hoe lang de return string wordt, die in een keer reserven ( een buffer allocatie, precies genoeg uninitialized geheugen ) en die in scan 2 vullen. Je schrijft alleen naar het geheugen wat je daadwerkelijk gaat retourneren -> 0 copies.
Nu, omdat je niet weet hoe lang de output string is, kopieer je bij de reallocaties elk karakter gemiddeld 1x. Hetzelfde geldt voor je char[256] oplossing, daar zal het toch uit gekopieerd moeten worden.
const char[]s optellen is niet efficient, omdat je elke keer een strlen() moet doen om te bepalen hoe lang dat is. Stop de chars een keer in een std::string, en de size() is beschikbaar in O(1) ipv O(n).
Een andere tip is om de add_br decision te hoisten. Nu branch je v.size() keer, dat hoeft maar 1 keer ( hij verandert niet tijdens de loop ).
Iha is het efficienter om int i en v[i] te vervangen door een string iterator, alhoewel het op de x86 niet uitmaakt.
Kortom, ga er niet van uit dat je weet waar de bottlenecks zitten. Ik heb recent een C programma herschreven in C++, en daarbij de char[]s vervangen door echte strings. Het programma deed niet veel meer dan strings manipuleren. De runtime ging van 16-24 uur naar 1 uur. Waarom? Ik gebruikte een profiler, en verbeterde wat er daadwerkelijk uitmaakte, de ene functie die in m'n eerste probeersel 4 uur duurde.
Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein