Jestem wielkim wielbicielem języka C++ i jednocześnie zagorzałym przeciwnikiem języków Pascalo-pochodnych. Chcę tutaj przedstawić moją opinię o tych językach i wytłumaczyć dlaczego wolę C++ od Pascala czy Delphi. Sam 4 lata pisałem w Pascalu i ponad rok w Delphi, więc mam pewne doświadczenie i możliwość porównania obu języków. Mam nadzieję, że ten artykuł przyda się osobom, które zastanawiają się na tym, który język wybrać w swoją dalszą podróż programistyczną.
Pewnego "miłego" dnia miałem napisać pewien projekt w Delphi. Zrobiłem już wcześniej coś podobnego w C++. Wyglądało to dosyć prosto, więc pomyślałem, że przepisanie tego na Delphi będzie proste i szybkie. Zasiadłem do Delphi po ponad rocznej przerwie no i tu zaczęły się piętrzyć problemy. Okazało się, że w Delphi trzeba było to wszystko znacznie obszerniej zakodować i użyć dodatkowych zasobów. Zacząłem ostro przeklinać Object Pascala. Projekt jakoś zakończyłem, jednak przypłaciłem to niezłym nadszarpnięciem nerwów. W tym właśnie czasie znienawidziłem Delphi. Dlatego postanowiłem napisać ten artykuł...
Ogólnie o historii języków programowania:
Język C++ stał się niekwestionowanym liderem wśród języków programowania ogólnego zastosowania.
Fakt ten wpłynął na jego bardzo gwałtowny rozwój. Próbą usystematyzowania języka było wprowadzenie w 1998 roku standardu ANSI/ISO C++.
Standard ten jest olbrzymi. Niezaprzeczalnym faktem jest, że język C++ jest jednym z najbardziej rozbudowanych w historii języków programowania.
Jest to jeden z niewielu języków, który doczekał się standardu i nadal jest szeroko używany.
Język C++ jest nie tylko bardzo dobry metodologicznie i efektywny, jeśli chodzi o wydajność skompilowanych programów, ale jest też językiem, w którym powstaje większość oprogramowania systemowego. W związku z tym wszelkie techniczne nowości są w jego środowisku implementowane najszybciej i najpełniej.
Cała praca jest dość niskopoziomowa - co wymaga odpowiedniego doświadczenia, ale zapewnia też wysoki poziom kontroli nad tym, co się robi,
wysoką niezawodność produktu końcowego i jego szeroko pojętą efektywność. Ogólnie C++ jest najodpowiedniejszy przy realizacji zadań systemowych,
bądź też złożonych algorytmicznie. Jest najlepszy do realizacji logiki aplikacji, wszystkiego tego,
co znajduje się na niższym poziomie niż sama komunikacja z użytkownikiem.
Język C++ jest najlepszy do tworzenia "betonowej konstrukcji" danego projektu.
Mimo że C# oraz Visual Basic umożliwiają dostęp do interfejsów Windows API, żaden z tych języków nie może rywalizować z immanentnymi możliwościami C++ do współpracy z istniejącym kodem Windows.
Większość systemów operacyjnych jest napisana w 90% w języku C/C++. Dlatego wywoływanie wszelkich funkcji systemu operacyjnego z poziomu programu C++ jest najszybsze i najwygodniejsze.
W Delphi aby wywołać niektóre funkcje systemowe Windows należy użyć odpowiednich bibliotek odpakowujących te funkcje w odpowiednie dla Delphi.
Mamy tu najczęściej problemy z innymi typami danych.
Funkcje Windows API używają pewnych typów danych, które mogą być nieznane programiście Delphi.
Większość parametrów w wywoływanych funkcjach API są wskaźnikami do jakichś typów danych.
C++ zapewnia programistom najwyższy stopień kontroli nad konstrukcją i sposobem działania programu. Zaawansowani programiści mogą za pomocą języka C++ tworzyć i implementować aplikacje działające szybciej i wydajniej, niż gdyby były napisane w innych językach, czy to natywnie wykorzystujących system Windows, czy też opartych na .NET.
Delphi to poszerzony język Object Pascal i przystosowany do tworzenia aplikacji pod systemy Windows.
Pascal stworzony przez Niklausa Wirtha w 1971 roku, pierwotnie służył celom edukacyjnym do nauki programowania strukturalnego.
Popularność Pascala w Polsce była większa niż w innych krajach ze względu na dostępność kompilatorów w pirackich wersjach (zanim pojawiło się prawo ochrony własności intelektualnej),
prostotę języka oraz jego popularyzację przez wyższe uczelnie.
Wcześniej było już C, stworzone przez Dennisa Ritchie'ego do programowania systemów operacyjnych i innych zadań niskiego poziomu. W roku 1973 w języku C udało się zaimplementować jądro (kernel) systemu operacyjnego Unix.
C stał się popularny poza Laboratoriami Bella (gdzie powstał) po 1980 roku, i stał się dominującym językiem do programowania systemów operacyjnych i aplikacji. Na bazie języka C w latach osiemdziesiątych Bjarne Stroustrup stworzył język C++,
który wprowadza możliwość programowania obiektowego.
Początkowo najważniejszą rzeczą wprowadzoną w C++ w stosunku do C było programowanie obiektowe,
później jednak wprowadzono do niego mnóstwo ulepszeń, czyniąc ten język wygodniejszym i bardziej elastycznym od swojego pierwowzoru.
Chciałbym tutaj podkreślić, że język C++ jest czymś zupełnie innym i o wiele lepszym niż język C. Język C++ jest jednak na tyle elastyczny, że pozwala także tworzyć kod w stylu czystego C. Ponadto C++ jest z kompatybilny wstecz z C (biblioteki przeznaczone dla C działają w C++).
Niektóre cechy języka C++:
- Klasy wraz z innymi elementami języków zorientowanych obiektowo takimi jak: dziedziczenie, metody wirtualne
- Dodatkowe ulepszenia klas, konstruktory, destruktory (język C++ był pierwszym językiem w którym użyto nazwy "konstruktor" w tym właśnie znaczeniu i pierwszym językiem, który posiadał destruktory)
- Szablony (wzorce) klas i funkcji
- Obsługa wyjątków
- Deklaracje zmiennych jako instrukcje (w ANSI C wszystkie zmienne lokalne funkcji musiały być zadeklarowane przed pierwszą jej instrukcją)
- Dynamiczna inicjalizacja zmiennych globalnych i lokalnych zmiennych statycznych (tzn. mogły być inicjalizowane wynikiem wywołanej funkcji)
- Przestrzenie nazw
- Makra
- Referencje
- Operatory new i delete
- Operator zasięgu (::) (w ANSI C nie istnieje możliwość odwołania się do zmiennej globalnej o tej samej nazwie, co zmienna lokalna)
- Dynamiczna kontrola typów RTTI
- Przeciążanie funkcji
- Przeciążanie (przeładowywanie) operatorów
- Wskaźniki do składowych (pól i metod)
- Funkcje rozwijalne (inline)
- "Szeroki" typ znakowy, wchar_t wraz ze wszystkimi zależnościami
- Operatory rzutowania: static_cast, dynamic_cast, reinterpret_cast i const_cast
Wskaźniki są bardzo potężnym aspektem języka. Wskaźniki dają programistom C++ bezpośredni dostęp do pamięci systemowej, pozwalając na tworzenie najbardziej wydajnych aplikacji. Operacje na wskaźnikach są w C++ bardzo łatwe. W Pascalu operowanie wskaźnikami jest raczej niewygodne.
Pisząc w C++ jesteśmy bliżej procesora i możemy przez to łatwo optymalizować kod (np. operując wskaźnikami).
Wywołania funkcji w C++ są szybsze niż w Delphi.
Programując w C++ chcę, aby program działał DOBRZE, tzn. zużywał jak najmniej zasobów komputera i był najbardziej optymalną implementacją rozwiązana dla danego problemu. Tylko C++ pozwala wykonać to jak najlepiej.
Składnia języka C++ pozwala na pisanie bardzo efektywnych programów przy stosunkowo niewielkim rozmiarze kodu.
Techniki obiektowo-orientowane są obecnie najlepszym sposobem, jaki znamy na pisanie dużych, kompleksowych aplikacji i systemów.
W Pascalu praktycznie nie ma obiektowości, a ta w Delphi jest nieprzemyślanie wykonana (np. polimorfizm) i to jeszcze w okrojonej postaci.
To jest kompletne niezrozumienie, czym jest programowanie obiektowe.
Programowanie obiektowe to absolutna podstawa we współczesnej pracy programisty.
W C++ mamy oddzielne pliki nagłówkowe, które bardzo ułatwiają programowanie obiektowe.
W Delphi nie ma zaawansowanych technik obiektowości jak np. template'y czyli szablony klas, które są już od dawna w C++.
Nawet projektanci Javy czy C# nie docenili szablonów. Wydawało się, że idea dziedziczenia przez wszystkie klasy po klasie Object (podobnie jak w Delphi) jest w stanie rozwiązać problemy programowania generycznego.
Szybko jednak okazało się, że kod tworzony w ten sposób staje się zawiły, nieczytelny i niewygodny w utrzymaniu.
C++ udostępnia całą generyczną bibliotekę STL (Standard Template Library) opierającą się wyłącznie na szablonach! STL zawiera algorytmy, pojemniki, iteratory oraz inne konstrukcje w formie szablonów, gotowe do użycia w programach.
W C++ mamy wielokrotne dziedziczenie (dziedziczenie klasy po więcej niż jednym przodku).
Zaletą dziedziczenia wielokrotnego jest to, że dzięki niemu możemy powiązać ze sobą niezależne od siebie typy klas.
Przydaje się to na przykład wtedy, gdy klasa pochodna ma mieć dwoistą naturę. Przykład:
class amfibia: public samochod, public lodka
C++ daje programistom pełny zestaw cech programowania obiektowego,
co umożliwia zastosowanie najszerszego zakresu technik programowania obiektowego.
C++ umożliwia prawdziwe dziedziczenie (inheritance) i wiązanie dynamiczne (dynamic binding), co pozwala staremu kodowi wywoływać nowy kod.
C++ jest fenomenem: pomimo, że jest językiem dość niskiego poziomu (w kierunku Assemblera) pozwala na bardzo abstrakcyjne i wygodne programowanie.
Użycie przeciążonych operatorów może ułatwić pisanie programu i sprawić, że notacja będzie bardziej naturalna np. przy operacjach na datach: dodawanie, odejmowanie.
Język C++ jest wieloparadygmatowy - można w nim pisać strukturalnie, obiektowo, generycznie oraz na dowolne sposoby mieszać te metody. Można nawet w nim pisać w stylu języka Pascal lub też na poziomie asemblera.
Można wybrać taki styl lub sposób, jaki nam w danej chwili odpowiada lub na jaki pozwala nam nasz poziom umiejętności.
Delphi jest jak klocki lego dla dzieci. Mamy tu pewną ilość klocków, z których można złożyć bardzo wiele różnych rzeczy, ale wszystko to będzie wyglądało bardzo kanciasto.
W C++ kod można dopieszczać w nieskończoność i przez to delektować się sztuką programistyczną.
Dla mnie programowanie to nie tylko stworzenie programu, ale przede wszystkim znalezienie najbardziej optymalnej drogi do celu. W C++ można w najbardziej bezpośredni i prosty a przez to elegancki sposób rozwiązywać dane problemy.
Pisanie w C++ to tworzenie z finezją kodu a w Delphi jest to zwykłe rąbanie młotkiem. Może przy pomocy młota i siekiery da się nieraz coś zrobić, tylko jak to będzie wyglądało...
W Pascalu często trzeba nachodzić się łukami i naokoło docierać do celu.
Niedoświadczonemu programiście może wydawać się, że w Pascalu wymóg stosowania wszędzie odpowiednich typów daje większe bezpieczeństwo tworzonemu kodowi.
Przy dużych projektach kompletnie to się nie sprawdza i doświadczony programista nie zyska na tym wiele a często jest to bardzo niewygodne.
Przymus kontroli typów danych jest wielką wadą tego języka. Pascal bardzo rygorystycznie podchodzi do kontroli typów, tj. sprawdza czy do zmiennej typu A nie próbuje się przypisać wartości typu B. Jest to dobra cecha języka dydaktycznego,
ale dla doświadczonego programisty może być bardzo uciążliwa.W programowaniu zabiegi w rodzaju rzutowania zmiennej typu całkowitego na typ Bool są częstą praktyką - w Pascalu kompilator się na to nie zgodzi.
Pascal sprawia też, że początkujący nie potrafią dokładnie zrozumieć architektury komputera. Przypomnę tu chociażby bezsensowne funkcje Ord i Chr, które nic nie robią - bo przecież niczym nie różni się znak ASCII 'a' od bajtu o wartości 97.
W Pascalu nie ma rozróżniania wielkości liter, co jest ograniczeniem przy tworzeniu nazw.
Mamy po prostu mniejszy zbiór możliwych nazw do zastosowania. Pod tym względem w C++ mamy większą swobodę - jest większe zróżnicowanie nazw. Dzięki temu kod może być czytelniejszy. Przykładowo możemy sobie założyć, że pola i metody z klas będą miały nazwy zaczynające się z wielkiej litery a tymczasowe i lokalne zmienne będą miały nazwy zaczynające się małą literą. Założenie takiej konwencji i wymagana przez język konsekwencja w przestrzeganiu jej, przyczyna się do znacznej poprawy czytelności kodu i szybszej orientacji: który obiekt/zmienna skąd pochodzi.
Dzięki rozróżnianiu wielkości liter w C++ można konsekwentnie stosować np. notację węgierską.
O elastyczności składni C++ oraz tym, że programowanie w tym języku jest z pewnością sztuką, przemawia chociażby istnienie różnych stylów pisania kodu źródłowego. Język C++ jest tak elastyczny i bogaty, że czasami może to być nawet nieco kłopotliwe, gdyż musimy wybierać jeden z wielu sposobów zapisania danej myśli-instrukcji.
Pisanie w C++ jest sztuką, gdyż możemy wybrać sobie własny (oryginalny) styl pisania.
Pisząc w Delphi czuję się jak operator jakiejś maszyny. Tutaj jedynie buduje sie program. W C++ się go tworzy (kreuje)!
Budując w Delphi program, korzystamy z dostępnych materiałów i technologii.
Tworząc w C++, kreujemy na swój sposób implementacje własnych pomysłów, mając możliwość z korzystania i wytwarzania odpowiednich dla nas materiałów i technologii.
Sam kod w C++ jest bardziej przejrzysty dzięki np.:
- użyciu klamer {} ograniczających bloki zamiast słów: begin..end
- pozbycia się niepotrzebnego słowa then, div
C++ ma przemyślaną składnię, której celem jest pisanie pielęgnowalnego kodu.
Ponadto składnia w C++ jest przystosowana do pisania zoptymalizowanego kodu, np.:
a+=5; (zwiększ o 5 wartość zmiennej a) - tylko jedna operacja.
W Pascalu mamy gorzej: a:=a+5 (oblicz wartość a+5 i podstaw ją do zmiennej a) - dwie operacje.
W Delphi można co najwyżej użyć tutaj procedury Inc(a, 5), jednak tylko gdy a jest typu całkowitego (ordinal). Dla liczb rzeczywistych ten zapis trzeba zamienić na a:=a+5.
W przypadku C++, przy zmianie typu zmiennej nie musimy zmieniać kodu - operator przypisania może działać na dowolnym typie zmiennej. Możemy oczywiście sami go sobie zdefiniować dla własnych obiektów, korzystając z przeładowania operatorów.
W C++ mamy możliwość definiowania nowej zmiennej w dowolnym miejscu w kodzie,
np. tylko dla wybranego bloku. Można dzięki temu czasem oszczędzić pamięć. Również sam kod bywa przez to czytelniejszy.
Zmienne są tam, gdzie je wykorzystujemy. Jest to bliższe filozofii obiektowości.
W Delphi wszystkie zmienne muszą być zdeklarowane na początku programu lub funkcji, niezależnie czy będą wykorzystane czy nie.
Oczywiście w C++ można zastosować styl Pascala i wszystkie zmienne ustawić na początku. W C++ jest zawsze wolność wyboru.
const M :Integer = 1234; const N :Integer = 5678; const K :Integer = M*N; //błąd // trzeba zapisać const K :Integer = 1234*5678;Ten sam problem jest ze zmiennymi. Nie można np. użyć takiego zapisu:
var A: array [1..M*N] of double; //błąd // trzeba zapisać var A: array [1..1234*5678] of double;
W C++ oczywiście nie ma takich problemów. Dzięki temu kod jest krótszy, czytelniejszy i bezpieczniejszy:
const int M = 1234; const int N = 5678; const int K = M*N; double A[M*N];
Ten problem staje się bardzo istotny, gdy mamy kilka tablic i testujemy kod na różnych rozmiarach:
//---Kod w C++: const int MAX = 1234; //Wystarczy tylko tutaj zmieniać rozmiar! double M[MAX*MAX]; //macierz współczynników double B[MAX]; //wektor wyrazów wolnych double X[MAX]; //dla wyniku double OdpX[MAX]; //odpowiedni wynik //---Kod w Delphi: const MAXWymiar: Integer = 1234; //Rozmiar musimy zmieniać w 6 miejscach! var M: array [0..1234*1234-1] of double; //macierz współczynników B: array [0..1234-1] of double; //wektor wyrazów wolnych X: array [0..1234-1] of double; //dla wyniku OdpX: array [0..1234-1] of double; //odpowiedni wynik
W Delphi w pętli for nie można użyć iteratora typu Int64. Nie da się skompilować coś takiego:
var i: Int64; ... For i:=1 To 10 Do ...
W Delphi wywołania funkcji bez parametrów zapisuje się bez nawiasów, przez co kod jest mniej czytelny, bo nie wiadomo, na pierwszy rzut oka, czy dany ciąg jest nazwą zmiennej lub stałej czy funkcji, np. czas := gettickcount.
W przypadku C++ od razu widać z czym mamy do czynienia: czas = GetTickCount().
W C++ mamy wyrażenia, które oprócz swego działania reprezentują sobą jakąś wartość, którą można używać w kolejnych wyrażeniach. Jest to bardzo wygodne, np. przy tworzeniu pętli. Można wtedy w elegancki i zwięzły sposób zapisać daną procedurę.
Przykładowy kod w C++:while ((w = DetMatrix(M,n)) != 0.0)
{if (w < 0.0) {...}
else {...}
}
To samo w Delphi trzeba zapisać znacznie obszerniej:
w := DetMatrix(M,n); while w <> 0.0 do begin if (w < 0.0) then begin ... end; else begin ... end; w := DetMatrix(M,n); end;W C++ jest o wiele wygodniejsze kodowanie zwracania rezultatu przez funkcję - po prostu używamy instrukcji return. Przykładowy kod:
if (Wymiar <= 1) return 0.0;W Delphi musimy się więcej napisać:
if Wymiar <= 1 Then begin RESULT := 0.0; exit; end;
C++ pozwala nam widzieć dany obiekt z odpowiedniej dla nas perspektywy. Dowolny obiekt można traktować w dowolny sposób np. jako liczbę, znak, ciąg tekstowy, wskaźnik czy tablicę. W Delphi wszystko jest na sztywno ustalane przez typy a potem, gdy chce się obiekty różnych typów porównać trzeba używać funkcji konwertujących z jednego typu na drugi.
Przykładowo w C++ tablicę można traktować jako wskaźnik na pierwszy element tej tablicy.
Dzięki temu można zoptymalizować kod przy odwoływaniu się do kolejnych elementów tablicy, za pomocą przesuwanego wskaźnika.
Żadne techniki udostępniane przez język nie zastąpią przemyślanej kontroli nad kodem przez samego programistę.
W C++ programista ma największą kontrolę nad tworzonym końcowym kodem.
Pisanie w Pascalu to jak tworzenie muzyki za pomocą prostego syntezatora. Wiadomo wszystko można na nim zagrać, tylko jak to będzie brzmiało i czy to zawsze będzie prawdziwa sztuka...?
Delphi może być użyteczne dla osób, które nie chcą zbytnio uczyć się programowania i chcą szybko pisać proste programiki lub tylko zaliczyć jakieś laborki na uczelni.
Delphi jest niszowe i popularne najczęściej wśród gimnazjalistów, licealistów, studentów. To jest środowisko dla entuzjastów i osób utrzymujących stary kod.
Prawdziwą potęgą jest jednak C++, to język dla profesjonalistów.
C++ jest na tyle elastyczny, że bez większych problemów można przepisać na ten język każdy program w Pascalu.
W drugą stronę nie zawsze jest to możliwe. Po prostu każdą konstrukcję zastosowaną w Pascalu można użyć też w C++.
(gdyby ktoś nie wiedział, w C++ jest także typ string oraz inne: pchar, WideChar)
Aplikacje w Delphi są tworzone głównie do obsługi baz danych.
Programując w Delphi jesteśmy ograniczeni tylko do jednego środowiska, czyli bibliotek VCL, jednego systemu Windows, tylko komputerów PC oraz tylko firmy - Borland, która tworzy najgorsze kompilatory. Programista Delphi nie ma żadnego wyboru wśród darmowych kompilatorów.
Natomiast znając C++ nie mamy takiego ograniczenia i możemy łatwo używać różnych środowisk, np.:
- Borland C++ Builder (biblioteki VCL)
- MS Visual C++ (biblioteki MFC, CLR z .NET)
- Linux (np. biblioteki QT i inne)
- Min GW Studio (biblioteki wxWidgets)
Poza tym programista, decydując się na wybór C++, ma szeroką ofertę narzędzi programistycznych, zarówno komercyjnych jak i darmowych.
Dostępnych jest mnóstwo kompilatorów pod różne platformy: Windows, Linux, Mac, HP-UX, Digital UNIX, BSD Unix, DGI, FreeBSD, AIX, Solaris.
Wymienię chociażby kilka darmowych kompilatorów i środowisk C++:
- GCC (GNU Compiler Collection)
- Cygwin www.cygwin.com
- Code::Blocks 1.0 RC2 (GCC 3.4.4 port pod Windows) www.codeblocks.org
- MinGW Developer Studio 2.05 (GCC 3.4.2 port pod Windows) www.parinyasoft.com/download.html
- DJGPP
- EMX 0.9
- RSX tools for GNU C/C++
- Borland C++ Compiler 5.5
- Borland Kylix 3 Open Edition
- Borland C++Builder 6 Personal
- Borland C++BuilderX Personal
- Microsoft Visual C++ Toolkit 2003
- Microsoft Visual C++ 2005 Express Edition
- Digital Mars www.digitalmars.com
- Macintosh Programmer's Workshop (MPW)
- Turbo C++ 1.01
- Open Watcom C/C++ 1.7 www.openwatcom.org
- Intel(R) C++ Compiler 6.0 for Linux
- Dev-C++ 4.9.9.0 (GCC 3.3.1 port pod Windows) www.bloodshed.net/devcpp.html
- wxDev-C++ http://wxdsgn.sourceforge.net/
- Quincy 2005 C++ 1.3 www.codecutter.net/tools/quincy/
- BVRDE v1.2b - IDE for C and C++ designed to make cross-platform development easy. http://bvrde.sourceforge.net
Więcej na www.januszg.hg.pl/teksty/kompilatory_c_cpp.html.
Język C++ jest wieloplatformowy. Używa się go do oprogramowania wszelkiego rodzaju komputerów, np.: PC, Macintosh, Amiga oraz wielkich superkomputerów.
C++ używa się nie tylko w oprogramowaniu komputerów, ale także w wielu różnych urządzeniach posiadających procesor, np. w telefonach komórkowych (system operacyjny Symbian), dekoderach telewizyjnych, maszynach produkcyjnych i wielu różnych mikro-urządzeniach.
W rankingu popularności technologii IT na polskim rynku pracy http://wlodarek.com/komercha/ (maj 2007) C++ jest na 14 miejscu a Delphi dopiero około pozycji 40.
Kompilatory C++ często posiadają optymalizację dla najnowszych procesorów np. Intel. Wsparcie oznacza m.in. wykorzystywanie przez kompilator wszystkich instrukcji procesorów, np. Streaming SIMD Extensions 2 (SSE2). Oczywiście wspierane są także starsze rozszerzenia np. MMX.
Z uwagi na powyższe zalety niemal zawsze tylko w języku C++ tworzone są gry i to nie tylko na PC, ale również na różne konsole (np. Xbox).
Jeśli chodzi o Windows i aplikacje multimedialne, to najpełniejsze i najbardziej optymalne wykorzystanie bibliotek DirectX uzyskać można tylko w języku C++.
(Tak na marginesie, jest pewien słynny problem w DX Managed (.NET). Gdy chce się stworzyć światło i zdefiniować jego typ, to pisze się light.Type=typ_swiatla, jednak w Delphi nie da się tego zrobić, bo użyte w bibliotekach Managed DX słowo Type jest kluczowym dla Pascal/Delphi i nie da się tego w Delphi .NET skompilować.)
Znajomość języka C++ pozwala na bardzo łatwe poznawanie innych nowych języków, które opierają się na jego składni, np.: JavaScript, Java, C#, D, PHP.
Niestety kompilator Builder C++ został napisany w Delphi. Skutki tego widać wyraźnie po generowanym kodzie, który jest często gorszy (mniej optymalny i chaotyczny) od tego generowanego np. przez Visual C++.
Swego czasu testowałem takie same kody skompilowane w Builderze i w Visual C++. Okazuje się że kod skompilowany w Visual może działać nawet kilka razy szybciej niż ten C++ Builderze!
Ponadto sam plik exe jest o wiele grubszy i zawiera często wiele niepotrzebnych śmieci. Raz po skompilowaniu w Builderze plik exe zawierał część jakiegoś pliku tekstowego, który akurat był w pamięci. Widać przez to, jaki chaos panuje w programach (kompilatorach) napisanych w Delphi. Szkoda, że nie ma takiego narzędzia jak Builder napisanego od podstaw w C++.
Aby nie być gołosłownym co do wydajności C++, poświęciłem swój czas i przeprowadziłem 14 rzetelnych testów szybkości wynikowych kodów różnych kompilacji.
Przetestowałem 12 kompilatorów C++, w tym 3 różne wersje portów pod Windows MinGW GCC i 3 wersje MS Visual C++.
Wszystkie testy (kompilacje) zostały uruchomione co najmniej 10 razy i wybrano najlepszy wynik. Jeśli chodzi o ustawienia kompilacji w kompilatorach, to oczywiście starałem się wybrać taką konfigurację aby wynikowy kod działał jak najszybciej. Ustawienia kompilacji Delphi 7 są tutaj.
Kody źródłowe C++ i Delphi są całkowicie ze sobą odpowiednio (algorytmicznie, implementacyjnie i logicznie) równoważne, z użyciem odpowiednio takich samych typów danych. Można to sprawdzić - podaję pełne kody źródłowe każdego testu!
Środowiska testu:
1. AMD: CPU Sempron 64 3200+ 1.94 GHz, 1GB DRAM DDR2 PC2-4300 (266 MHz) 533 MHz, WinXP SP2 32-bit
2. Intel: CPU Pentium 4 - 3 GHz, 512 MB RAM DDR PC3200 (200 MHz), WinXP SP2 32-bit
Wyniki: Czas w milisekundach;
Liczba punktów = czas najlepszego / dany czas *100 %.
1. Prosty test: obliczenie 50 000 000 razy w = sin(w) + w, zaczynając od w=1.0 typu double.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| MS Visual C++ 2005 (8.00.50727.42) | 2156 | 100,00% | MS Visual 2005 (8.00.50727.42) | 1922 | 100,00% |
| MS Visual C++ 6.0 | 3343 | 64,49% | Intel C++ 10.0.025 | 2094 | 91,79% |
| MS Visual C++ 2003 (7.1) | 3343 | 64,49% | MS Visual C++ 2003 (7.1) | 3515 | 54,68% |
| Open Watcom C/C++ 1.7 | 3343 | 64,49% | MS Visual C++ 6.0 | 3516 | 54,66% |
| DigitalMars D v2.0 | 3469 | 62,15% | Open Watcom C/C++ 1.7 | 3516 | 54,66% |
| DigitalMars C++ 8.49 | 3469 | 62,15% | DigitalMars C++ 8.49 | 3750 | 51,25% |
| Intel C++ 10.0.026 | 3641 | 59,21% | Delphi 7.0 PE | 3781 | 50,83% |
| Delphi 7.0 PE | 3828 | 56,32% | DigitalMars D v2.0 | 3781 | 50,83% |
| Borland C++ Builder 6.0 Canterwood | 4328 | 49,82% | Borland C++ Builder 6.0 Canterwood | 5453 | 35,25% |
| Turbo C++ Builder 10.0.2288.4251 | 4500 | 47,91% | Turbo C++ Builder 10.0.2288.4251 | 5453 | 35,25% |
| MinGW Dev. Studio 2.05 (GCC 3.4.2) | 7328 | 29,42% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 14719 | 13,06% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 7328 | 29,42% | MinGW Dev. Studio 2.05 (GCC 3.4.2) | 14734 | 13,04% |
| Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 7828 | 27,54% | Code::Blocks v1.0 RC2 (GCC 3.4.4) | 15078 | 12,75% |
Widać tu, że kompilatory MS Visual C++ najlepiej optymalizują kod przy operacjach matematycznych na liczbach rzeczywistych.
2. Kolejny test - faktoryzacja liczby całkowitej. Algorytm dzieli daną liczbę L przez kolejne liczby nieparzyste do pierwiastka kwadratowego z L.
Procedura działa na 64-bitowych liczbach całkowitych ze znakiem. W kodzie użyłem typu __int64.
Okazało się, że w Delphi nie ma typu unsigned __int64 i musiałem użyć w tym przypadku typu signed __int64, co dwukrotnie zawęża zbiór możliwych do użycia liczb. Innym problemem okazała się konwersja z typu rzeczywistego na __int64. Trzeba było użyć dodatkowej zmiennej, bo nie dało się tego zrobić w jednej instrukcji.
Oczywiście w Delphi, przy pętlach for nie można ustalić rozmiaru kroku, więc trzeba było pozamieniać wszystkie pętle for na repeat..until lub while..do. Ponadto trzeba było jeszcze pozamieniać wszystkie znaki / na div oraz {,} na begin,end co sprawiło zaciemnienie kodu źródłowego w stosunku do C++. Mojej irytacji przy pisaniu w Delphi było więcej...
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| DigitalMars D v2.0 | 11734 | 100,00% | DigitalMars D v2.0 | 12437 | 100,00% |
| DigitalMars C++ 8.49 | 11750 | 99,86% | DigitalMars C++ 8.49 | 12437 | 100,00% |
| Open Watcom C/C++ 1.7 | 12016 | 97,65% | Open Watcom C/C++ 1.7 | 12906 | 96,37% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 14093 | 83,26% | Delphi 7.0 PE | 13906 | 89,44% |
| Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 14093 | 83,26% | Borland C++ Builder 6.0 Canterwood | 14328 | 86,80% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 14453 | 81,19% | Turbo C++ Builder 10.0.2288.4251 | 14328 | 86,80% |
| Borland C++ Builder 6.0 Canterwood | 14750 | 79,55% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 14984 | 83,00% |
| Delphi 7.0 PE | 14796 | 79,31% | Dev-C++ 4.9.9.0 (GCC 3.4.2) | 15234 | 81,64% |
| Turbo C++ Builder 10.0.2288.4251 | 15015 | 78,15% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 15454 | 80,48% |
| MS Visual C++ 6.0 | 20140 | 58,26% | MS Visual C++ 2003 (7.1) | 22609 | 55,01% |
| MS Visual C++ 2003 (7.1) | 20500 | 57,24% | MS Visual C++ 6.0 | 22640 | 54,93% |
| MS Visual C++ 2005 (8.00.50727.42) | 20656 | 56,81% | MS Visual 2005 (8.00.50727.42) | 22750 | 54,67% |
| Intel C++ 10.0.026 | 21968 | 53,41% | Intel C++ 10.0.025 | 23094 | 53,85% |
Trochę zdziwiła mnie tutaj słaba pozycja Visual C++ w teście faktoryzacji - prawie dwukrotnie słabsza od DigitalMars D.
Być może nie pogrzebałem dostatecznie w ustawieniach kompilacji (jest ich sporo) lub kompilator akurat słabo optymalizuje operacje na liczbach 64-bitowych.
Najlepsza okazała się kompilacja w DigitalMars D, chociaż kod został napisany w stylu C++ (język D również umożliwia pisanie kodu w stylu C i C++).
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| Open Watcom C/C++ 1.7 | 6125 | 100,00% | Open Watcom C/C++ 1.7 | 6891 | 100,00% |
| DigitalMars D v2.0 | 6312 | 97,04% | DigitalMars D v2.0 | 7250 | 95,05% |
| Borland C++ Builder 6.0 Canterwood | 6469 | 94,68% | MS Visual C++ 6.0 | 7875 | 87,50% |
| Delphi 7.0 PE | 6515 | 94,01% | MS Visual C++ 2003 (7.1) | 7890 | 87,34% |
| MS Visual C++ 6.0 | 6515 | 94,01% | Borland C++ Builder 6.0 Canterwood | 7984 | 86,31% |
| Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 6531 | 93,78% | Turbo C++ Builder 10.0.2288.4251 | 8031 | 85,81% |
| Turbo C++ Builder 10.0.2288.4251 | 6625 | 92,45% | Delphi 7.0 PE | 8140 | 84,66% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 6703 | 91,38% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 8234 | 83,69% |
| DigitalMars C++ 8.49 | 6797 | 90,11% | DigitalMars C++ 8.49 | 8500 | 81,07% |
| MS Visual C++ 2003 (7.1) | 6875 | 89,09% | Intel C++ 10.0.025 | 8766 | 78,61% |
| Intel C++ 10.0.026 | 6922 | 88,49% | MS Visual 2005 (8.00.50727.42) | 8875 | 77,65% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 7000 | 87,50% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 11187 | 61,60% |
| MS Visual C++ 2005 (8.00.50727.42) | 7016 | 87,30% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 11640 | 59,20% |
4. Szukanie liczb doskonałych w przedziale od 3 do 500 000. Procedura operuje na 32-bitowych liczbach całkowitych ze znakiem (int/Integer).
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| Turbo C++ Builder 10.0.2288.4251 | 5266 | 100,00% | MS Visual 2005 (8.00.50727.42) | 3406 | 100,00% |
| MS Visual C++ 2003 (7.1) | 5281 | 99,72% | DigitalMars C++ 8.49 | 3421 | 99,56% |
| MS Visual C++ 2005 (8.00.50727.42) | 5281 | 99,72% | MS Visual C++ 2003 (7.1) | 3421 | 99,56% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 5296 | 99,43% | DigitalMars D v2.0 | 3437 | 99,10% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 5296 | 99,43% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 3484 | 97,76% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 5296 | 99,43% | Intel C++ 10.0.025 | 3484 | 97,76% |
| Borland C++ Builder 6.0 Canterwood | 5375 | 97,97% | MS Visual C++ 6.0 | 3485 | 97,73% |
| Delphi 7.0 PE | 5390 | 97,70% | Open Watcom C/C++ 1.7 | 3500 | 97,31% |
| MS Visual C++ 6.0 | 5578 | 94,41% | Borland C++ Builder 6.0 Canterwood | 3500 | 97,31% |
| Open Watcom C/C++ 1.7 | 5593 | 94,15% | Delphi 7.0 PE | 3547 | 96,02% |
| Intel C++ 10.0.026 | 5593 | 94,15% | Turbo C++ Builder 10.0.2288.4251 | 3562 | 95,62% |
| DigitalMars D v2.0 | 5781 | 91,09% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 3625 | 93,96% |
| DigitalMars C++ 8.49 | 5843 | 90,12% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 3640 | 93,57% |
5. Mnożenie dwóch macierzy o wyrazach typu double. Rozmiary: M = 1000; N = 700; K = 500; A[M*N] x B[N*K] = C[M*K]. Tablice statyczne.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| MS Visual C++ 2005 (8.00.50727.42) | 3079 | 100,00% | Intel C++ 10.0.025 | 3328 | 100,00% |
| MS Visual C++ 6.0 | 3141 | 98,03% | MS Visual 2005 (8.00.50727.42) | 3453 | 96,38% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 3234 | 95,21% | Open Watcom C/C++ 1.7 | 3469 | 95,94% |
| Intel C++ 10.0.026 | 3281 | 93,84% | MS Visual C++ 2003 (7.1) | 3500 | 95,09% |
| Open Watcom C/C++ 1.7 | 3266 | 94,27% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 3546 | 93,85% |
| MS Visual C++ 2003 (7.1) | 3328 | 92,52% | MS Visual C++ 6.0 | 3547 | 93,83% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 3438 | 89,56% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 3562 | 93,43% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 3562 | 86,44% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 3859 | 86,24% |
| DigitalMars C++ 8.49 | 4306 | 71,50% | DigitalMars C++ 8.49 | 4390 | 75,81% |
| Turbo C++ Builder 10.0.2288.4251 | 4438 | 69,38% | Turbo C++ Builder 10.0.2288.4251 | 4484 | 74,22% |
| DigitalMars D v2.0 | 5953 | 51,72% | DigitalMars D v2.0 | 4828 | 68,93% |
| Borland C++ Builder 6.0 Canterwood | 6031 | 51,05% | Borland C++ Builder 6.0 Canterwood | 4953 | 67,19% |
| Delphi 7.0 PE | 6218 | 49,52% | Delphi 7.0 PE | 5015 | 66,36% |
6. Mnożenie tych samych macierzy, ale tutaj o wyrazach typu float (Single).
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| MS Visual C++ 2005 (8.00.50727.42) | 1609 | 100,00% | MS Visual 2005 (8.00.50727.42) | 1921 | 100,00% |
| MS Visual C++ 6.0 | 1734 | 92,79% | Intel C++ 10.0.025 | 2125 | 90,40% |
| Intel C++ 10.0.026 | 1734 | 92,79% | Open Watcom C/C++ 1.7 | 2140 | 89,77% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 1734 | 92,79% | MS Visual C++ 2003 (7.1) | 2187 | 87,84% |
| MS Visual C++ 2003 (7.1) | 1875 | 85,81% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 2187 | 87,84% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 1875 | 85,81% | MS Visual C++ 6.0 | 2188 | 87,80% |
| Open Watcom C/C++ 1.7 | 1906 | 84,42% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 2203 | 87,20% |
| Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 2234 | 72,02% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 2515 | 76,38% |
| DigitalMars C++ 8.49 | 3266 | 49,27% | DigitalMars C++ 8.49 | 4047 | 47,47% |
| DigitalMars D v2.0 | 3312 | 48,58% | DigitalMars D v2.0 | 4062 | 47,29% |
| Borland C++ Builder 6.0 Canterwood | 3313 | 48,57% | Borland C++ Builder 6.0 Canterwood | 4140 | 46,40% |
| Turbo C++ Builder 10.0.2288.4251 | 3343 | 48,13% | Turbo C++ Builder 10.0.2288.4251 | 4140 | 46,40% |
| Delphi 7.0 PE | 3359 | 47,90% | Delphi 7.0 PE | 4203 | 45,71% |
Z ostatnich dwóch testów widać, że Delphi najwolniej operuje na liczbach rzeczywistych.
7. Najmniejsza Wspólna Wielokrotność na liczbach typu signed __int64 (Int64)
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| Open Watcom C/C++ 1.7 | 4093 | 100,00% | Open Watcom C/C++ 1.7 | 4125 | 100,00% |
| DigitalMars C++ 8.49 | 4703 | 87,03% | DigitalMars D v2.0 | 4937 | 83,55% |
| DigitalMars D v2.0 | 4703 | 87,03% | DigitalMars C++ 8.49 | 5031 | 81,99% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 5422 | 75,49% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 5828 | 70,78% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 5531 | 74,00% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 5843 | 70,60% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 5532 | 73,99% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 5844 | 70,59% |
| MS Visual C++ 6.0 | 7171 | 57,08% | MS Visual C++ 6.0 | 8046 | 51,27% |
| MS Visual C++ 2003 (7.1) | 7187 | 56,95% | MS Visual 2005 (8.00.50727.42) | 8046 | 51,27% |
| MS Visual C++ 2005 (8.00.50727.42) | 7187 | 56,95% | MS Visual C++ 2003 (7.1) | 8062 | 51,17% |
| Intel C++ 10.0.026 | 7203 | 56,82% | Intel C++ 10.0.025 | 8109 | 50,87% |
| Turbo C++ Builder 10.0.2288.4251 | 11390 | 35,94% | Delphi 7.0 PE | 16328 | 25,26% |
| Delphi 7.0 PE | 11609 | 35,26% | Turbo C++ Builder 10.0.2288.4251 | 16421 | 25,12% |
| Borland C++ Builder 6.0 Canterwood | 11953 | 34,24% | Borland C++ Builder 6.0 Canterwood | 16657 | 24,76% |
8. Sortowanie rekurencyjnym algorytmem QuickSort statycznej (na stosie) tablicy 20 000 000 liczb typu int (Integer).
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| MS Visual C++ 2005 (8.00.50727.42) | 1843 | 100,00% | Intel C++ 10.0.025 | 1969 | 100,00% |
| MS Visual C++ 2003 (7.1) | 1844 | 99,95% | MS Visual C++ 2003 (7.1) | 2032 | 96,90% |
| Intel C++ 10.0.026 | 1844 | 99,95% | MS Visual 2005 (8.00.50727.42) | 2047 | 96,19% |
| MS Visual C++ 6.0 | 1890 | 97,51% | MS Visual C++ 6.0 | 2109 | 93,36% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 1921 | 95,94% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 2125 | 92,66% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 1937 | 95,15% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 2156 | 91,33% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 2047 | 90,03% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 2250 | 87,51% |
| Delphi 7.0 PE | 2093 | 88,06% | Open Watcom C/C++ 1.7 | 2281 | 86,32% |
| Turbo C++ Builder 10.0.2288.4251 | 2078 | 88,69% | Delphi 7.0 PE | 2297 | 85,72% |
| Borland C++ Builder 6.0 Canterwood | 2140 | 86,12% | Borland C++ Builder 6.0 Canterwood | 2391 | 82,35% |
| Open Watcom C/C++ 1.7 | 2391 | 77,08% | Turbo C++ Builder 10.0.2288.4251 | 2437 | 80,80% |
| DigitalMars D v2.0 -tablica na stercie! | 2515 | 73,28% | DigitalMars C++ 8.49 -tablica na stercie! | 2485 | 79,24% |
| DigitalMars C++ 8.49 -tablica na stercie! | 2735 | 67,39% | DigitalMars D v2.0 -tablica na stercie! | 2500 | 78,76% |
9. Sortowanie rekurencyjnym algorytmem QuickSort statycznej (na stosie) tablicy 10 000 000 liczb typu double.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| MS Visual C++ 2005 (8.00.50727.42) | 1218 | 100,00% | Intel C++ 10.0.025 | 1390 | 100,00% |
| MS Visual C++ 2003 (7.1) | 1219 | 99,92% | MS Visual C++ 2005 (8.00.50727.42) | 1437 | 96,73% |
| Intel C++ 10.0.026 | 1562 | 77,98% | MS Visual C++ 2003 (7.1) | 1453 | 95,66% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 1562 | 77,98% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 1843 | 75,42% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 1578 | 77,19% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 1859 | 74,77% |
| MS Visual C++ 6.0 | 1656 | 73,55% | MS Visual C++ 6.0 | 2000 | 69,50% |
| Borland C++ Builder 6.0 Canterwood | 1781 | 68,39% | DigitalMars D v2.0 -tablica na stercie! | 2125 | 65,41% |
| Delphi 7.0 PE | 1782 | 68,35% | Delphi 7.0 PE | 2328 | 59,71% |
| Open Watcom C/C++ 1.7 | 1812 | 67,22% | Open Watcom C/C++ 1.7 | 2359 | 58,92% |
| DigitalMars D v2.0 -tablica na stercie! | 1828 | 66,63% | DigitalMars C++ 8.49 -tablica na stercie! | 2453 | 56,67% |
| Turbo C++ Builder 10.0.2288.4251 | 1953 | 62,37% | Borland C++ Builder 6.0 Canterwood | 2469 | 56,30% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 2047 | 59,50% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 2937 | 47,33% |
| DigitalMars C++ 8.49 -tablica na stercie! | 2187 | 55,69% | Turbo C++ Builder 10.0.2288.4251 | 2953 | 47,07% |
10. Szyfrowanie algorytmem RC4 500 razy statycznej (na stosie) tablicy 10 000 000 liczb typu unsigned char (Byte).
Kody źródłowe: C++, D, Delphi (Tu można zobaczyć ile więcej trzeba się napisać w Delphi.)
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| Open Watcom C/C++ 1.7 | 37469 | 100,00% | MS Visual C++ 2005 (8.00.50727.42) | 30406 | 100,00% |
| Intel C++ 10.0.026 | 44984 | 83,29% | Intel C++ 10.0.025 | 30437 | 99,90% |
| MS Visual C++ 2005 (8.00.50727.42) | 45016 | 83,23% | Code::Blocks v1.0 RC2 (GCC 3.4.4) | 30687 | 99,08% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 45094 | 83,09% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 30859 | 98,53% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 45375 | 82,58% | MS Visual C++ 2003 (7.1) | 31375 | 96,91% |
| MS Visual C++ 6.0 | 48016 | 78,03% | MS Visual C++ 6.0 | 31859 | 95,44% |
| DigitalMars C++ 8.49 | 48312 | 77,56% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 33766 | 90,05% |
| Turbo C++ Builder 10.0.2288.4251 | 49469 | 75,74% | DigitalMars C++ 8.49 | 34812 | 87,34% |
| Borland C++ Builder 6.0 Canterwood | 50391 | 74,36% | Borland C++ Builder 6.0 Canterwood | 36172 | 84,06% |
| MS Visual C++ 2003 (7.1) | 50829 | 73,72% | Turbo C++ Builder 10.0.2288.4251 | 36375 | 83,59% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 53390 | 70,18% | Open Watcom C/C++ 1.7 | 39235 | 77,50% |
| Delphi 7.0 PE | 61000 | 61,42% | Delphi 7.0 PE | 39593 | 76,80% |
| DigitalMars D v2.0 | 63437 | 59,06% | DigitalMars D v2.0 | 40468 | 75,14% |
11. Wyznacznik macierzy stopnia 11 na wyrazach typu double.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
|---|---|---|---|---|---|
| MS Visual C++ 6.0 | 13453 | 100,00% | Intel C++ 10.0.025 -sator kompil. | 8703 | 100,00% |
| MS Visual C++ 2005 (8.00.50727.42) | 14062 | 95,67% | MS Visual C++ 6.0 | 16625 | 52,35% |
| Intel C++ 10.0.026 | 14984 | 89,78% | MS Visual C++ 2005 (8.00.50727.42) | 17484 | 49,78% |
| MS Visual C++ 2003 (7.1.6030) | 16062 | 83,76% | MS Visual C++ 2003 (7.1.6030) | 17500 | 49,73% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1)-O1 | 16828 | 79,94% | Open Watcom C/C++ 1.7 -6r | 19969 | 43,58% |
| Open Watcom C/C++ 1.7 -6r | 17062 | 78,85% | DigitalMars D v2.0 | 19984 | 43,55% |
| DigitalMars C++ 8.49 | 18047 | 74,54% | Borland C++ Builder 6.0 Canterwood | 19563 | 44,49% |
| Delphi 7.0 PE | 18578 | 72,41% | Turbo C++ Builder 10.0.2288.4251 | 19968 | 43,58% |
| Borland C++ Builder 6.0 Canterwood-bez fast! | 19438 | 69,21% | Delphi 7.0 PE | 20593 | 42,26% |
| DigitalMars D v2.0 | 19796 | 67,96% | Dev-C++ 4.9.9.0 (GCC 3.3.1)-O1 | 21656 | 40,19% |
| Turbo C++ Builder 10.0.2288.4251 | 20422 | 65,88% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 27469 | 31,68% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4)-bez O | 31984 | 42,06% | Code::Blocks v1.0 RC2 (GCC 3.4.4)-bez O | 27781 | 31,33% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 32407 | 41,51% | DigitalMars C++ 8.49 | 31094 | 27,99% |
12. Liczenie układu 2000 równań metodą eliminacji Gaussa na wyrazach typu double z wyborem maksymalnego wyrazu do dzielenia z wierszy.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
| MS Visual C++ 2005 (8.00.50727.42) | 14000 | 100,00% | MS Visual C++ 2003 (7.1.6030) | 12985 | 100,00% |
| Intel C++ 10.0.026 | 14406 | 93,43% | Intel C++ 10.0.026 | 13000 | 99,88% |
| MS Visual C++ 6.0 | 14984 | 93,43% | MS Visual C++ 2005 (8.00.50727.42) | 13047 | 99,52% |
| MS Visual C++ 2003 (7.1.6030) | 14985 | 93,53% | DigitalMars D v2.0 | 13078 | 99,29% |
| Open Watcom C/C++ 1.7 | 14968 | 91,24% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 13140 | 98,82% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 15344 | 91,90% | Open Watcom C/C++ 1.7 | 13156 | 98,70% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 15234 | 89,87% | DigitalMars C++ 8.49 | 13172 | 98,58% |
| DigitalMars D v2.0 | 15578 | 87,67% | MS Visual C++ 6.0 | 13188 | 98,46% |
| DigitalMars C++ 8.49 | 15969 | 97,18% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 13219 | 98,23% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 16937 | 82,66% | Code::Blocks v1.0 RC2 (GCC 3.4.4) | 13765 | 94,33% |
| Borland C++ Builder 6.0 Canterwood | 20329 | 68,87% | Borland C++ Builder 6.0 Canterwood | 16547 | 78,47% |
| Turbo C++ Builder 10.0.2288.4251 | 20453 | 68,45% | Turbo C++ Builder 10.0.2288.4251 | 16546 | 78,48% |
| Delphi 7.0 PE | 32015 | 43,73% | Delphi 7.0 PE | 20031 | 64,82% |
13. Liczenie układu 2000 równań metodą eliminacji Gaussa na wyrazach typu double z wyborem maksymalnego wyrazu do dzielenia z WIERSZY i KOLUMN.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
| MS Visual C++ 2005 (8.00.50727.42) | 25718 | 100,00% | MS Visual C++ 2005 (8.00.50727.42) | 19984 | 100,00% |
| MS Visual C++ 2003 (7.1.6030) | 25984 | 98,98% | MS Visual C++ 2003 (7.1.6030) | 20437 | 97,78% |
| Open Watcom C/C++ 1.7 | 26094 | 98,56% | Intel C++ 10.0.026 | 21218 | 94,18% |
| MS Visual C++ 6.0 | 26891 | 95,64% | Open Watcom C/C++ 1.7 | 26172 | 76,36% |
| DigitalMars C++ 8.49 | 26984 | 95,31% | MS Visual C++ 6.0 | 26656 | 74,97% |
| Intel C++ 10.0.026 | 27641 | 93,04% | DigitalMars D v2.0 | 26656 | 74,97% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 28703 | 89,60% | DigitalMars C++ 8.49 | 26781 | 74,62% |
| DigitalMars D v2.0 | 29734 | 86,49% | Dev-C++ 4.9.9.0 (GCC 3.3.1) | 27141 | 73,63% |
| Code::Blocks v1.0 RC2 (GCC 3.4.4) | 31219 | 82,38% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 27546 | 72,55% |
| Dev-C++ 4.9.9.0 (GCC 3.3.1) | 31531 | 81,56% | Code::Blocks v1.0 RC2 (GCC 3.4.4) | 37047 | 53,94% |
| Delphi 7.0 PE | 39359 | 65,34% | Delphi 7.0 PE | 48767 | 40,98% |
| Borland C++ Builder 6.0 Canterwood | 76640 | 33,56% | Borland C++ Builder 6.0 Canterwood | 94250 | 21,20% |
| Turbo C++ Builder 10.0.2288.4251 | 76750 | 33,51% | Turbo C++ Builder 10.0.2288.4251 | 95000 | 21,04% |
14. Liczenie wartości liczby Fibonacciego na wyrazach typu unsigned int algorytmem rekurencyjnym.
Kody źródłowe: C++, D, Delphi
| Kompilacja uruchomiona na AMD | Czas | Pkt | Kompilacja uruchomiona na Intel | Czas | Pkt |
| DigitalMars D v2.0 | 17484 | 100,00% | Borland C++ Builder 6.0 Canterwood | 15656 | 100,00% |
| MS Visual C++ 2005 (8.00.50727.42) | 18578 | 94,11% | Turbo C++ Builder 10.0.2288.4251 | 15781 | 99,21% |
| MS Visual C++ 2003 (7.1) | 18594 | 94,03% | DigitalMars D v2.0 | 23016 | 68,02% |
| Intel C++ 10.0.026 | 18797 | 93,01% | Delphi 7.0 PE | 23532 | 66,53% |
| MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 19109 | 91,50% | Intel C++ 10.0.026 | 23594 | 66,36% |
| Turbo C++ Builder 10.0.2288.4251 Update2 | 19593 | 89,24% | DigitalMars C++ v8.49 | 24485 | 63,94% |
| MS Visual C++ 6.0 | 19828 | 88,18% | Open Watcom C/C++ 1.7 | 25609 | 61,13% |
| Dev-C++ 4.9.9.0 (GCC 3.4.2) | 19906 | 87,83% | MS Visual C++ 2003 (7.1) | 25719 | 60,87% |
| Borland C++ Builder 6.0 Canterwood | 20812 | 84,01% | MS Visual C++ 2005 (8.00.50727.42) | 25735 | 60,84% |
| Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 22766 | 76,80% | MS Visual C++ 6.0 | 25750 | 60,80% |
| Open Watcom C/C++ 1.7 | 22985 | 76,07% | Dev-C++ 4.9.9.0 (GCC 3.4.2) | 27453 | 57,03% |
| DigitalMars C++ v8.49 | 23422 | 74,65% | MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 27500 | 56,93% |
| Delphi 7.0 PE | 25797 | 72,02% | Code::Blocks V 1.0 RC2 (GCC 3.4.4) | 27984 | 56,39% |
PODSUMOWANIE TESTÓW
Zliczając dokładnie (bez zaokrągleń) sumę punktów ze wszystkich testów otrzymujemy ogólne wyniki:
| Kompilacja uruchomiona na AMD | Suma pkt | Kompilacja uruchomiona na Intel | Suma pkt |
|---|---|---|---|
| 1. MS Visual C++ 2005 (8.00.50727.42) | 1273,79% | 1. Intel C++ 10.0.025 | 1223,60% |
| 2. Open Watcom C/C++ 1.7 | 1224,01% | 2. MS Visual C++ 2005 (8.00.50727.42) | 1183,02% |
| 4. MS Visual C++ 6.0 | 1185,41% | 3. Open Watcom C/C++ 1.7 | 1136,56% |
| 4. MS Visual C++ 2003 (7.1) | 1189,70% | 4. MS Visual C++ 2003 (7.1) | 1128,54% |
| 7. Intel C++ 10.0.026 | 1169,22% | 5. MS Visual C++ 6.0 | 1072,61% |
| 6. Dev-C++ 4.9.9.0 (GCC 3.3.1) | 1149,45% | 6. Dev-C++ 4.9.9.0 (GCC 3.3.1) | 1050,02% |
| 7. MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 1117,16% | 7. DigitalMars D v2.0 | 1049,89% |
| 9. DigitalMars C++ 8.49 | 1092,37% | 8. MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 1026,53% |
| 10. Code::Blocks v1.0 RC2 (GCC 3.4.4) | 1053,01% | 9. DigitalMars C++ 8.49 | 1025,53% |
| 10. DigitalMars D v2.0 | 1078,71% | 10. Code::Blocks v1.0 RC2 (GCC 3.4.4) | 955,84% |
| 12. Turbo C++ Builder 10.0.2288.4251 | 955,82% | 11. Borland C++ Builder 6.0 Canterwood | 910,90% |
| 11. Borland C++ Builder 6.0 Canterwood | 940,39% | 12. Turbo C++ Builder 10.0.2288.4251 | 902,98% |
| 13. Delphi 7.0 PE | 931,35% | 13. Delphi 7.0 PE | 895,10% |
Ogólnie razem: liczone dokładnie - bez zaokrągleń. Dokładne wyniki zawarłem w pliku Excela.
| Kompilacja uruchomiona na AMD i Intel | Suma pkt | Proporcja |
|---|---|---|
| 1. MS Visual C++ 2005 (8.00.50727.42) | 2456,81% | 100,00% |
| 2. Intel C++ 10.0.026 | 2392,82% | 97,40% |
| 3. Open Watcom C/C++ 1.7 | 2360,57% | 96,08% |
| 4. MS Visual C++ 2003 (7.1) | 2318,24% | 94,36% |
| 5. MS Visual C++ 6.0 | 2258,02% | 91,91% |
| 6. Dev-C++ 4.9.9.0 (GCC 3.3.1) | 2199,48% | 89,53% |
| 7. MinGW Dev. Studio C++ 2.05 (GCC 3.4.2) | 2143,68% | 87,25% |
| 8. DigitalMars D v2.0 | 2128,60% | 86,64% |
| 9. DigitalMars C++ 8.49 | 2117,90% | 86,21% |
| 10. Code::Blocks v1.0 RC2 (GCC 3.4.4) | 2008,85% | 81,77% |
| 11. Turbo C++ Builder 10.0.2288.4251 | 1858,80% | 75,66% |
| 12. Borland C++ Builder 6.0 Canterwood | 1851,30% | 75,35% |
| 13. Delphi 7.0 PE | 1826,45% | 74,34% |
Jak widać wyraźnie, nie myliłem się, w sumie Delphi okazał się najgorszy w wydajności wynikowego kodu!
Bardzo dobre okazały się kompilatory Visual C++ ze stajni Microsoftu.
Najlepszym kompilatorem jest MS Visual C++ 2005 a już jest wersja 2008beta!
Ponadto pliki exe stworzone przez ten kompilator są bardzo małe (mniejsze nawet o 6-15 razy od innych kompilacji), co jest również dużą zaletą,
gdyż zwykle w innych kompilatorach, ustawienia kompilacji zmniejszające rozmiar skutkują zmniejszoną szybkością kodu.
Równie dobry jest komercyjny kompilator Intel C++ 10.0.025 oraz darmowy Open Watcom C/C++!
Najgorsze i to znacznie okazały się kompilatory firmy Borland. Ponadto C++ Builder źle (inaczej niż większość) traktuje czasem niektóre zapisy kodu,
np. ++i%=256. Potwierdziły się tutaj wszelkie negatywne opinie o kompilatorach Borlanda.
Jeśli chodzi o preferencje kompilatorów co do określonej architektury procesora, to oczywiście Intel C++ tworzy kod najbardziej zoptymalizowany pod procesory Intela
(jednak nieraz taki kod nie uruchamia się na platformie AMD).
Z testów także wynika, że kompilacje DigitalMars D v2.0 zwykle szybciej działają na procesorze Intela.
Poniżej fragment artykułu Adama Sawickiego "Programowanie jako praca twórcza".
"Co jest istotą programowania? Chociaż informatyce bliżej do nauk technicznych (czy wręcz matematycznych) niż do dziedzin humanistycznych, to jednak programowanie jest pracą twórczą.
Dlatego opiera się nie tylko na wiedzy, ale w bardzo dużym stopniu także na doświadczeniu praktycznym. Wymaga kreatywności i samodzielności, twórczego myślenia i umiejętności rozwiązywania problemów.
Programowanie jest jednocześnie nauką i sztuką. Istnieje nawet takie pojęcie jak
poezja kodu. W tych instrukcjach dla maszyny istotnie musi być coś magicznego,
skoro programiści postrzegają je tak odmiennie od pozostałych ludzi, dla których programowanie jawi się jako zagadnienie nudne,
wręcz jako czarna robota. Co to takiego?
Kod, jak każdy tekst, oddaje pewne intencje autora, jest środkiem wyrazu, odzwierciedla jego niepowtarzalny styl.
Każde zadanie różni programiści rozwiążą na różne sposoby. Kod to jednak coś więcej niż tekst. Jego można nie tylko czytać.
On się wykonuje - działa - można obserwować efekty jego pracy - i właśnie to jest moim zdaniem tak niezwykłe w programowaniu."
W języku C++ mamy większą kontrolę nad tym, co chcemy wyrazić. Jest to język bardziej elastyczny.
Dla mnie osobiście pisanie w C++ jest sztuką a w tworzenie w Delphi do zwykłe rzemiosło.
W Delphi operujemy prostymi instrukcjami: "idź tam", "zrób to".
Język C++ to coś więcej niż narzędzie do tworzenia programów.
Programowanie w C++ może przypominać poezję, w której można w jednym wyrażeniu wyrazić wiele myśli, na różne sposoby. Przykładowo:
++i %= 256; //jest równoważne (z wyjątkiem Borlanda niestety)... ++i; i %= 256; //jest równoważne... i = ++i % 256; //jest równoważne... i = (i+1) % 256; //w stylu Pascala i := (i+1) mod 256;
C++ ma swój smak. To nie tylko narzędzie, ale także pewna filozofia myślenia i cały mikroświat.
Język C++ jest nieco trudniejszy od Delphi do nauczenia się, jednak daje nam za to większą przestrzeń wyrażania idei.
Język ten udostępnia użytkownikowi bardzo wiele sposobów programowania.
C++ wymaga od programisty większej wiedzy, doświadczenia i uwagi, ale za to daje większe możliwości. Przypominać to może trochę pracę bez rękawic ochronnych - wydaje się to trochę niebezpieczne, jednak jest o wiele bardziej wygodne i precyzyjne.
Poza tym każda bardziej zaawansowana technologia wymaga o jej użytkownika dodatkowej wiedzy. Przykładowo, aby móc jeździć samochodem trzeba mieć prawo jazdy.
Świat Delphi przyrównałbym do miasta, w którym nie ma innej możliwości, jak chodzenie tylko po ściśle wyznaczonych do tego miejscach i przejściach. Nie można przejść przez ulicę, jeżeli nie ma tam przejścia dla pieszych i nie świeci się zielone światło. Może to być bezpieczne, ale często bywa niewygodne i zajmuje wiele czasu. Delphi przypomina państwo policyjne.
C++ to miasto, w którym można chodzić gdzie i kiedy się chce. Wymaga to oczywiście pewnej rozwagi, ale za to można pewne rzeczy zrobić szybciej i łatwiej. Przykładowo można, po upewnieniu się, że nie przejeżdża żaden pojazd, wyskoczyć szybko po gazetę na drugą stronę ulicy nie robiąc żadnych niepotrzebnych łuków i nie przestrzegając zbędnych procedur.
W Delphi często mamy do czynienia z przerostem formy nad treścią. Jest to język zbyt "rozgadany"- wszystko trzeba explicite napisać. Delphi jest ponadto pełen ograniczeń - traktuje on programistę, jak potencjalnego przestępcę, który tylko czyha aby coś zepsuć.
C++ szanuje programistę. Traktuje go, jak twórczego wspólnika - nie ogranicza jego kreatywności i ekspresji. W świecie C++ jest większe zaufanie do rozwagi programisty, a przez to jest większa swoboda i poziom wolności. Kosztem swobody jest oczywiście wymagana większa odpowiedzialność programisty. Jednak, jedynie dla początkujących programistów C++ ta, odpowiedzialność może wydawać się uciążliwa. Wraz z doświadczeniem, odpowiedzialność ta przechodzi w nawyk - automatyczny odruch i pozostaje nam już tylko swoboda tworzenia kodu.
Delphi daje nieco większe bezpieczeństwo, ale za to kosztem sporych ograniczeń. Pisząc w Delphi czuję się jak w niewygodnym kombinezonie ochronnym, w grubych rękawicach i w masce gazowej na głowie.
Delphi widzę jako coś kanciastego, sztywnego, z góry ustalonego. Jest to język mało abstrakcyjny i zbyt konserwatywny. Pełen kontroli i braku swobody.
Tworząc w C++ mamy większą świadomość rzeczywistości tworzonego kodu.
Delphi to język, który ogranicza naszą świadomość. Nie zdajemy sobie sprawy nad niektórymi przeprowadzanymi przez kompilator operacjami.
W C++ można w najbardziej bezpośredni, zwięzły i najbardziej elegancki sposób przekazać maszynie swoją myśl.
Pisząc w Delphi i nie znając C++ nie ma się świadomości, że może istnieć inny lepszy świat wyrażania swoich myśli.
Dopiero poznając C++ można zdać sobie sprawę jak "ciasny" jest język Delphi.
Pierwszym językiem kompilowanym, który poznałem był Pascal. Jak chyba większość w Polsce zacząłem programowanie od tego języka. Pisałem w nim 4 lata a potem ponad rok w Delphi. Wydawało mi się, że jest to najlepszy język, najbardziej wygodny i nie ma sensu poznawać innego. Gdy zaczynałem uczyć się C++, będąc wciąż pod wpływem myślenia pascalowego uważałem, że C++ to coś okropnego i niepotrzebnego. Na początku składnia C++ wydawała mi się zawiła i ciężkostrawna. Jednak z czasem, po przestawieniu swojego myślenia, zobaczyłem, że kod w C++ może być poezją, trzeba ją tylko umieć zrozumieć. Całkowicie zaraziłem się ceplusplusem. Język ten to całkiem nowy sposób myślenia i podejścia do tworzonego kodu. Dopiero z czasem zgłębiając filozofię C++ poznaje się piękno tego języka.
Inną analogią różnic między Delphi a C++ może być różnica między konsolą do gier a komputerem. Konsola jest wygodniejsza w użytkowaniu i bezpieczniejsza (nie zawiesi się), ale za to jest ograniczona tylko do gier. Komputer może być trudniejszy w obsłudze, jednak można go wykorzystać do bardzo wielu różnych rzeczy.
Ogólna konkluzja jest zatem następująca.
C++ to język trudniejszy i wymagający większego doświadczenia, ale za to daje większe możliwości i wygodę.
Delphi to język prostszy, ale za to bardziej ograniczony i mniej wygodny.
Jedyny plus Delphi to jego bardzo szybki kompilator, ale wynika to z prostoty języka Object Pascal.
Piękno i smak C++ poznaje się z czasem, tak jak i piękno sztuki.
Delfiarstwu mówię stanowcze - NIE!
Zachęcam wszystkich ograniczających się do programowania tylko w Delphi do wyjścia z tego Matrixa, jakim jest świat tego języka, uwolnienia się i poszerzenia swojej świadomości oraz przejścia na stronę C++ :).
Z niecierpliwością czekam na spopularyzowanie się jeszcze lepszego języka od C++ a mianowicie języka D. Język D powstał na bazie C/C++, jest bardziej rozbudowany, zawiera wiele nowych technik, jest wygodniejszy i dzięki "agresywnej optymalizacji" często generuje jeszcze bardziej optymalny kod wynikowy.
Oto kilka produkcji nieosiągalnych przy pomocy Delphi, tylko za pomocą C++ i Assemblera, czyli intra 64KB:
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22]
[kkrieger - gra 3D w 96KB!] [intro 177KB]
c += ++c += c++ + ++c; Artur Czekalski (SaToR) www.epokaY.net/artur/programowanie.php