Benchmark práce s objekty v jazycích C++, Vala a Python
Již delší dobu se chystám programovat v jazyku Vala. Jde o objektově orientovaný jazyk postavený nad
GObject. Mima jiného mě zajímala i rychlost výsledného programu. Připravil sem tedy test, který porovnává rychlost práce s třídami a instancemi s ostatními jazyky, ve kterých programuji.
20.9.2011 10:00 |
Ondřej Tůma
| Články autora
| přečteno 6797×
Kompilátor jazyka Vala sám nevytváří binární kód, ale vygeneruje kód v čistém C, který je kompilován běžným kompilátorem, typicky gcc. A protože je inspirován vysokoúrovňovými jazyky a orientován právě na GObject, je interní práce s objekty od ostatních jazyků odlišná. Objekty jsou udržovány v paměti obdobně jako v jazyku Python pomocí referencí. Počítají se tedy reference na objekt, a pokud jsou vynulovány, objekt je z paměti uvolněn.
Test spočívá v definici jednoduché třídy Foo, která má jeden parametr typu integer. Tato třída je následně milionkrát vytvořena, je vyčten její parametr (zavolána metoda instance) a následně zničena. Ještě než přijde řada na zdrojové kódy testů, rád bych uvedl, že jsem si vědom, že kód není nijak optimalizován na konkrétní jazyky a v řadě případů by šel jistě napsat daleko efektivněji. Účelem testu však bylo zjistit, jaké jsou nároky na CPU při běžném použití.
Následují jednotlivé zdrojové kódy, případně jejich variace a výsledný čas měřený nástrojem time. Čas byl měřen třikrát a v grafech jsou použity průměry naměřených hodnot.
C++
V případě C++ jsem do testu začlenil použití třídy (class) bez předka. Rozdíl v použití struktury (struct) je velmi malý a pro srovnání s jazykem Vala vlastně ne zcela vypovídající.
int count = 1000*1000;
class Foo { private: int i;
public: Foo(int i){ this->i = i; } int geti(){ return this->i; } };
int main(int argv, char ** argc){ for (int i = 0; i < (count); i++){ Foo foo(i); foo.geti(); }
return 0; }
C++ class: avg real 0m0.038s 0m0.039s 0m0.027s 0m0.035s user 0m0.040s 0m0.032s 0m0.028s 0m0.033s sys 0m0.000s 0m0.000s 0m0.000s 0m0.000
A také dědění třídy Glib.Object z glibmm, což je c++ wrapper nad glib knihovnou. Rozdíl mezi glibmm a Valou je zejména v tom, že výsledný program nevyžaduje žádnou další knihovnu ke svému provozu.
#include <glibmm/object.h> #include <glibmm/init.h>
int count = 1000*1000;
class Foo : public Glib::Object { private: int i;
public: Foo(int i):Glib::Object(){ this->i = i; } int geti(){ return this->i; } };
int main(int argv, char ** argc){ Glib::init(); for (int i = 0; i < (count); i++){ Foo foo(i); foo.geti(); }
return 0; }
C++ GObject: avg real 0m5.222s 0m5.308s 0m5.225s 0m5.252s user 0m5.140s 0m5.176s 0m5.124s 0m5.174s sys 0m0.004s 0m0.016s 0m0.012s 0m0.011s
Vala
Jazyk Vala může přistupovat k třídám různými způsoby. Nejpodobnější třídě tak jak ji známe z C++ je Struct, který je značně omezen v případě použití jako třídy, nicméně režie okolo vytváření a práce se strukturou se blíží režii v C++, což je dáno zejména tím, že se nepracuje s referencemi.
int count = 1000*1000;
struct Foo { public int i; public Foo.new(int i){ this.i = i; }
public int geti(){ return this.i; } }
public int main(string[] args){ for (int i = 0; i < (count); i++){ Foo foo = Foo(){ i = i }; foo.geti(); }
return 0; }
Vala struct: avg real 0m0.102s 0m0.102s 0m0.105s 0m0.103s user 0m0.088s 0m0.096s 0m0.096s 0m0.093s sys 0m0.008s 0m0.000s 0m0.004s 0m0.004s
Další možnost jak vytvořit odlehčenou třídu je použití direktivy [Compact].
int count = 1000*1000;
[Compact] class Foo { public int i;
public Foo(int i){ this.i = i; }
public int geti(){ return this.i; } }
public int main(string[] args){ for (int i = 0; i < (count); i++){ Foo foo = new Foo(i); foo.geti(); }
return 0; }
Vala compat class: avg real 0m0.393s 0m0.395s 0m0.399s 0m0.396s user 0m0.388s 0m0.396s 0m0.392s 0m0.392s sys 0m0.000s 0m0.004s 0m0.004s 0m0.003s
V jazyce Vala lze dále dělit třídy na ty které nejsou děděny z GLib.Object a ty které jsou. Tyto dvě skupiny budou nejčastěji používané a dva předchozí testy jsou malým porušením testu, neboť se snaží optimalizovat výsledný kód. Ty třídy které nejsou potomky GLib.Object mají o něco menší režii.
int count = 1000*1000;
class Foo { private int i;
public Foo(int i){ this.i = i; }
public int geti(){ return this.i; } }
public int main(string[] args){ for (int i = 0; i < (count); i++){ Foo foo = new Foo(i); foo.geti(); }
return 0; }
Vala class: avg real 0m2.712s 0m2.758s 0m2.404s 0m2.634s user 0m2.620s 0m2.716s 0m2.372s 0m2.569s sys 0m0.004s 0m0.012s 0m0.012s 0m0.009s
Na závěr tedy kód a čas v případě použití třídy, která je potomkem GLib.Object. Je asi vhodné dodat, že právě tyto třídy jsou v jazyce Vala preferované, což je vzhledem k nejčastějšímu použití jazyka pochopitelné.
int count = 1000*1000;
class Foo: GLib.Object { private string name; private int i;
public Foo(string name, int i){ this.name = name; this.i = i; }
public int geti(){ return this.i; } }
public int main(string[] args){ for (int i = 0; i < (count); i++){ Foo foo = new Foo("This is funcking foo", i); foo.geti(); }
return 0; }
Vala GObject: avg real 0m6.042s 0m6.052s 0m6.142s 0m6.079s user 0m5.956s 0m5.932s 0m6.040s 0m5.976s sys 0m0.004s 0m0.012s 0m0.008s 0m0.008s
Python
Jak už bylo zmíněno, i Python používá ke správě objektů reference. A jelikož je Python jeden z mých hlavních programovacích jazyků, začlenil i jeho tři testy.
První test používá třídu bez předka. Jde o vlastně starý koncept tříd v Pythonu, který je udržován zejména kvůli zpětné kompatibilitě.
count = 1000*1000
class Foo: def __init__(self, name, i): self.name = name self.i = i
def geti(self): return self.i
for i in xrange(count): foo = Foo("This is funcking foo", i) foo.geti()
Python class: avg real 0m6.052s 0m5.771s 0m6.066s 0m5.963s user 0m5.888s 0m5.636s 0m5.912s 0m5.812s sys 0m0.004s 0m0.020s 0m0.012s 0m0.012s
V druhém testu je použita třída object. Jde tedy o standardní způsob vytváření objektů. Takto vytvořené třídy a jejich instance mají některé další možnosti, a je to poznat i na režii CPU.
count = 1000*1000
class Foo(object): def __init__(self, name, i): self.name = name self.i = i
def geti(self): return self.i
for i in xrange(count): foo = Foo("This is funcking foo", i) foo.geti()
Python Object: avg real 0m7.129s 0m7.611s 0m6.910s 0m6.883s user 0m6.972s 0m6.484s 0m6.768s 0m6.741s sys 0m0.020s 0m0.020s 0m0.028s 0m0.023s
Poslední test stejně jako v C++ nebo Vale používá třídu poděděnou z gobject.GObject. Zde už režie cpu dosahovala poněkud extrémních hodnot.
import gobject
count = 1000*1000
class Foo(gobject.GObject): def __init__(self, name, i): gobject.GObject.__init__(self) self.name = name self.i = i
def geti(self): return self.i
for i in xrange(count): #glib.init()
foo = Foo("This is funcking foo", i) foo.geti()
Pthon GObject: avg real 0m39.760s 0m39.194s 0m39.332s 0m39.760s user 0m38.990s 0m38.518s 0m38.658s 0m38.772s sys 0m0.032s 0m0.020s 0m0.040s 0m0.031s
Grafy
Obr1: Použití základních tříd jazyka.
Obr2: Použití tříd odvozených od GObject implementace v daném jazyku.
Pár slov na závěr
Z uvedených výsledků je zřejmé, že si jazyk Vala nestojí zase až tak špatně. Nicméně vzhledem k tomu, že jde o jazyk určený zejména k tvorbě grafických programů, je škoda, že chybí srovnání s jazyky C# (Mono) a Java. Stejně tak zde chybí test GObjectu v čistém C, který je značněji komplikovanější na použití, bylo by však vidět jak moc si člověk pohorší s výkonem výsledné aplikace.
Výsledný program nebyl nijak optimalizován, to znamená že kompilace probíhala bez dalších parametrů. Stejně tak sem si vědom, že jednotlivé jazyky používají různé vlastní optimalizace a ty, i když nejsou předmětem testu ovlivňují výsledky. A v konečné fázi si rozhodně nemyslím, že typická aplikace vytváří a následně ničí milion objektů. Na druhou stranu rozsáhlá aplikace může takových objektů mít opravdu mnoho, což je ale zcela jiná kapitola.
Jednoznačnou výhodu Valy proti C++ s glibmm vidím zejména v novém přístupu k programování. Jde o jiný jazyk, podobný spíše vysokoúrovňovým jazykům, který je ale šitý na míru GObjectu, tedy GTK+ knihovně. Výsledný kód je ale kompilovaný do binární podoby externím programátorem, a tak nejsou zapotřebí žádné další knihovny, což je vidět i na velikostech výsledných binárek.
Verze pro tisk
|
Příspívat do diskuze mohou pouze registrovaní uživatelé.
|
|

Vyhledávání software

Vyhledávání článků
28.11.2018 23:56 /František Kučera Prosincový sraz spolku OpenAlt se koná ve středu 5.12.2018 od 16:00 na adrese Zikova 1903/4, Praha 6. Tentokrát navštívíme organizaci CESNET. Na programu jsou dvě přednášky: Distribuované úložiště Ceph (Michal Strnad) a Plně šifrovaný disk na moderním systému (Ondřej Caletka). Následně se přesuneme do některé z nedalekých restaurací, kde budeme pokračovat v diskusi.
Komentářů: 1
12.11.2018 21:28 /Redakce Linuxsoft.cz 22. listopadu 2018 se koná v Praze na Karlově náměstí již pátý ročník konference s tématem Datová centra pro business, která nabídne odpovědi na aktuální a často řešené otázky: Jaké jsou aktuální trendy v oblasti datových center a jak je optimálně využít pro vlastní prospěch? Jak si zajistit odpovídající služby datových center? Podle jakých kritérií vybírat dodavatele služeb? Jak volit vhodné součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně datové centrum spravovat? Jak co nejlépe eliminovat možná rizika? apod. Příznivci LinuxSoftu mohou při registraci uplatnit kód LIN350, který jim přinese zvýhodněné vstupné s 50% slevou.
Přidat komentář
6.11.2018 2:04 /František Kučera Říjnový pražský sraz spolku OpenAlt se koná v listopadu – již tento čtvrtek – 8. 11. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma umění a technologie, IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
4.10.2018 21:30 /Ondřej Čečák LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář
18.9.2018 23:30 /František Kučera Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
9.9.2018 14:15 /Redakce Linuxsoft.cz 20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business.
Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář
12.8.2018 16:58 /František Kučera Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář
16.7.2018 1:05 /František Kučera Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář
Více ...
Přidat zprávičku
 Poslední diskuze
31.7.2023 14:13 /
Linda Graham iPhone Services
30.11.2022 9:32 /
Kyle McDermott Hosting download unavailable
13.12.2018 10:57 /
Jan Mareš Re: zavináč
2.12.2018 23:56 /
František Kučera Sraz
5.10.2018 17:12 /
Jakub Kuljovsky Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?
Více ...
|