C++ kontra Delphi

Nowa wersja testu kompilatorów - 2013 rok

Zobacz testy wydajności

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.

Kolejnym problemem jest deklaracja stałych. W Delphi stałe liczbowe można zainicjalizować tylko jawnie zapisanymi liczbami. Nie można korzystać z wartości poprzednich stałych. Nie przejdzie np. coś takiego:
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++.

TESTY SZYBKOŚCI 12-stu kompilatorów C++ oraz Delphi 7.0 Personal.


Nowa wersja testu kompilatorów - 2013 rok

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++).

3. Następny test - ta sama faktoryzacja, tym razem kolejnych 32-bitowych liczb całkowitych typu unsigned int (uint, Longword): od 2^32-1 do 2^32-10001
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 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%
wykres

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.

Spostrzeżenia

Włączenie opcji optymalizacji w kompilatorze nie zawsze skutkuje przyspieszeniem działania kodu wynikowego. Nieraz efekt jest wręcz odwrotny, tzn. kod wtedy działa wolniej! Przykładowo:
- dla testu nr 13 w Code::Blocks v1.0 RC2 (GCC 3.4.4) najszybszy kod uzyskałem przy wyłączonych wszystkich optymalizacjach!
- dla większości testów w MS Visual C++ 6.0 wybór Code Generation\Processor: Blend* daje szybszy kod niż, gdy ustalimy Pentium Pro
- dla testów nr 02, 07 w Dev-C++ najszybszy kod uzyskałem przy najmniejszej optymalizacji
Poza tym optymalizacja kodu może skutkować w błędach obliczeń na liczbach rzeczywistych (np. w Code::Blocks w teście nr 11).

Ogólnie

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

Nowa wersja testu kompilatorów - 2013 rok