Nedávno jsem kompiloval kód pro vyhodnocování pravidel (business rules engine) pro různé platformy. Při složitějších pravidlech a velkých datech je vyhodnocování poměrně výpočetně náročné, takže se nabízí srovnání rychlosti výsledného kódu:
clang | 720 ms |
GCC 4.6 | 810 ms |
VC++ (verifikovatelný kód) | 2200 ms / 3400 ms (VS2011) |
VC++ (nativní kód) | 5500 ms / 3300 ms (WinRT) |
VC++ (řízený kód, neřízená data) | 7200 ms / 4600 ms (VS2011) |
Uvedené časy nevypovídají zhola nic o kvalitě překladače nebo rychlosti nativního či řízeného kódu, neboť ve výsledku se projevuje pouze rychlost STL. Vede clang (použil jsem LLVM 3.0 s novou STL knihovnou libc++). STL v GCC 4.6 evidentně také naplno využívá možností C++11 (zejména move sémantiku), protože čas je velmi podobný.
Časy nativního kódu a řízeného kódu s neřízenými daty také příliš nepřekvapí, STL ve VC++ rychlostí nevyniká (navíc pokud je mi známo, zde je STL starší a nevyužívá nových možností C++11, takže novější verze by se nejspíše přiblížila rychlostí clangu a GCC).
Poněkud ovšem překvapuje pomalost verifikovatelného kódu . Vlastní program je zcela stejný (kromě pár jinak expandovaných maker, např. použití jmenného prostoru cliext místo std pro kontejnery, jinak by kód samozřejmě nešel přeložit). V kontejnerech se používají handly, takže se nic nekopíruje, a navíc odpadají destruktory (vyhodnocování pravidel nealokuje moc paměti, když už jsou načtená, takže GC se neaktivoval). Zbývá závěr, že implementace STL/CLR je mizerná. To ostatně potvrzují benchmarky i na blogu Microsoftu, které srovnávají výkon STL/CLR s kontejnery v BCL.
NB: V clangu a GCC jsem použil -O2, ve VC++ konfiguraci Release.
Zajímavý je rozdíl např. mezi STL řetězci v GCC a VC++. GCC verze řetězce se dá volně zaměnit za obyčejný 'char *'. Není to ovšem char *, ale ukazuje dovnitř struktury složené z hlavičky a samotného řetězce. VC++ řetězce jsou union{16B buffer, char*} + hlavička. Pokud je řetězec menší než 15 char (1 znak je vyhrazen na ''), použije se fixní buffer. Jinak se použije dynamicky alokovaný buffer.
Rychlost STL je v přímé opozici ke spolehlivosti a bezpečnosti STL.
Microsoft provádí kontroly parametrů a dalších věcí, které třeba gcc nikoli.
Osobně nejrychlejší implementaci STL nechci. Protože jakmile uděláte chybu jako programátor, vše se zhroutí a můžete na ní dny přicházet. Microsoft vám to řekne hned assertem, kde jste ujel.
Autor se zabývá vývojem kompilátorů a knihoven pro objektově-orientované programovací jazyky.
Přečteno 35 404×
Přečteno 24 418×
Přečteno 23 161×
Přečteno 19 655×
Přečteno 16 905×