C++ czy Delphi

Pokaż mi co zgodnego ze standardem, nie kompiluje kompilator VC++9.0. Potem zastanów się, na ile jest to przydatne i jak bardzo przeszkadza to w pisaniu softu.

Na co dzień piszę duże projekty w językach C++ i C# i dobrze wiem na co pozwalają kompilatory obydwu języków

Powolna kompilacja kompilatora C++, jest ściśle zależna od statycznego typowania. Różnica pomiędzy językami C++, C# i Java jest taka, że język C++ nie może zbudować kompletnej listy typów, użytych w kodzie programu, przed procesem kompilacji. To znacznie proces kompilacji wydłuża.

Twoja argumentacja jest chybiona. Małe dziecko uczy się języka angielskiego tak samo szybko jak języka polskiego, różnice w składni języka nie maja większego znaczenia. Jednak to jak szybko nauczysz się drugiego języka zależy od tego, jakiego języka nauczyłeś się w pierwszej kolejności.

Język C++ jest trudniejszy, ale po nim innych języków uczy się dużo łatwiej.

Sam udowadniasz, że to czy coś wygląda źle jest zależne od programisty a zwalasz winę na język.

Tyle że mit o przenośności, nabił Javie popularności. Gdyby prostota języka miałaby decydować o jego popularności, to C# przebiłby Javę, bo jest zdecydowanie lepiej od niej poukładany.

U mnie się kompilator nie gubi.

Od kiedy to język odpowiada za niewiedzę programistów?

Ten komunikat niesie informację o lokalizacji błędu.

I do takich zastosowań Java się nadaje - w oczekiwaniu na operacje IO, sprawdzać czy aby przypadkiem nie wyjechaliśmy poza przydzielony bufor pamięci.

Bierz Javę, lub C#, ale skoro nie dajesz nam innego wyboru niż między Delphi a C++, to bierz Delphi. Teraz ok?

Brak wsparcia dla exportowania definicji wzorców (słowo kluczowe export). Przy intensywnym używaniu wzorców 10 plikowy projekt potrafi się kompilować kilka minut, bo kompilator jest zmuszony rekompilować wielokrotnie te same definicje wzorców w nagłówkach. Upierdliwe jak ■■■■■■■. Inny przykład, że nawet VC++ może sobie być zgodny ze standardem, ale kiedyś projekt trzeba będzie przeportować np. na MacOSX i wtedy miej Boże w opiece tych programistów, którzy będą to robić. I nie, nie mam na myśli tylko niekompatybilności bibliotek, ale również niekompatybilności na poziomie składni i jej interpretacji. Portowałem kilka programów pomiędzy różnymi systemami i kompilatorami, i czasem tego typu prroblemy wymuszały przeprojektowywanie pokaźnych partii kodu (bo. np. gcc miało problemy ze specjalizacjami wzorców).

Pisałem już, że C++ jest przesadnie skomplikowany i sprawia kłopoty nie tylko programistom, ale i kompilatorom. To, że nie da się zbudować tej listy wynika z powalonego sposobu budowania projektów C++ (patrz punkt: brak modularyzacji).

Ale wysiłek włożony w nauczenie się C++ oraz C# lub Java jest dużo większy niż wysyłek włożony w nauczenie się samego C# lub Java.

Nie ma to jak uczyć się dla samego faktu uczenia.

Czytanie ze zrozumieniem się kłania. Jest zależne i od programisty, i od języka. Jak język do bani, to najlepszy programista nie napisze ładnego kodu. Napisz mi czytelny kod w Brainfucku. :smiley:

  1. C# był za późno.

  2. C# nie oferuje nic rewolucyjnego ponad Javę. Parę __drobnych__ ulepszeń to za mało by powtórzyć taki sukces. Java i C# oferują za to b. dużo ponad C++.

Języki są dla programistów, nie programiści dla języków. Mnie nawet nie chodzi o to, że C++ jest skomplikowany, bo to kwestia bardziej historyczna niż technologiczna, tylko o to, że jest PRZESADNIE skomplikowany jak na dzisiejsze realia. I są języki, które oferują tyle samo lub więcej, a równocześnie są łatwiejsze do nauki i lepiej uporządkowane.

Do takich i nie tylko takich.

Do wszystkich, gdzie jest przede wszystkim ważne RÓWNOCZEŚNIE bezpieczeństwo i bardzo wysoka wydajność. C++ oferuje albo jedno albo drugie, choć osiągnięcie takiego poziomu bezpieczeństwa i przewidywalności działania jak w Javie chyba nie jest w ogóle możliwe. Dopisz sobie wszystkie takie sprawdzania w programach w C++ i nie masz szans (pozostając przy standardowych kompilatorach dostępnych na rynku) pobić wydajności Javy nawet o 1%. Ba, dorzuć samą gwarancję poprawnego zarządzania pamięcią (nie obchodzi mnie czy przez smartpointery czy pełne GC) i z wydajnością wylądujesz bardzo daleko za Javą… Dzieje się tak dlatego, że JVM ma do dyspozycji wszystkie optymalizacje, które mogą stosować statyczne kompilatory C++ oraz kilka bardzo silnych optymalizacji, których w kompilatorach C++ nigdy nie będzie. M.in. biased locking i lock elision, które w aplikacjach wieloprocesorowych potrafią dawać bardzo duże zyski. W C++ nawet nie ma pojęcia wątku, więc z czym do ludzi. Widziałem aplikacje serwerowe, które po przepisaniu z C++ na Javę przyspieszały… 3-krotnie.

Jeżyk? :stuck_out_tongue:

Pytanie tylko, czy chcemy pracować 10 razy dłużej (a więc i 10 razy zwiększyć koszty) aplikacji, która będzie 10% wydajniejsza. Generalnie mało firm pójdzie na taki “zysk”, nieco lepszy sprzęt jest tańszy niż praca specjalistów.

Znając Brainfucka pewno łatwiej byłoby się nauczyć C++, niż ucząc się go od podstaw. Ale to chyba nie jest metoda.

Masz wyjątkowo dobry wzrok :stuck_out_tongue:

Ad 1. Za późno w jakim sensie? Ok, później od Javy, a tak poza tym?

Ad 2. Mógłbyś wymienić tych “parę drobnych ulepszeń”?

Nic. 15 lat temu było wspaniałe.

Ale zadałeś głupie pytanie - chcesz porównania dwóch zupełnie innych języków. Tylko po co? One służą w zasadzie do zupełnie innych zadań. Na dodatek nie bierzesz pod uwagę innych, nieraz ciekawszych technologii, o których zrobił się tutaj zresztą offtop :wink:

Delphi to ślepa uliczka, lepiej już zajmij się C++.

No, z tym 10x to pewnie lekka przesada, ale tak gdzieś 2-4x to zysku jest. Przynajmniej takie są moje odczucia (a programowałem dużo i w jednym i w drugim). Głównie oszczędza się na lepszych IDE, krótszym czasie rekompilacji, dużo szybszym poprawianiem błędów (brak “undefined behaviour”), mniejszą liczbą “sprytnych hacków” znalezionych w cudzym kodzie i pokaźną biblioteką standardową.

Za późno, żeby zdobyć tak dużą popularność jak Java i takie wsparcie firm trzecich. Choć może to nie jest tylko kwestia “za późno”, ale też polityki Microsoftu. Co do drobnych ulepszeń - no w samym języku jest nieco więcej bajerków typu delegaty, propertiesy czy argumenty domyślne, lepiej są zrobione genericsy (tu jest duży plus dla C#). Jedni uważają, że to dobrze, drudzy że źle. Np. moim zdaniem konwersje implicit to ZŁO i celowo do Javy ich nie dodano. Jak już jakaś firma poszła w Javę, to zysk z przenoszenia się na C# byłby zbyt mały by zrównoważyć koszty i ryzyko z tym związane. W przypadku migracji C++ -> C# lub C++ -> Java długofalowe korzyści mogą być znacznie większe.

Z Delphi jest ten problem, że przestało się rozwijać i na dodatek ma fatalny marketing (tzn. nie ma marketingu praktycznie w ogóle). Mimo to Object Pascala bardzo miło wspominam. Jako pierwszy język do nauki jest w sam raz, bo jest jednak lepiej uporządkowany od C++, nie niesie za sobą takiego bagażu wstecznej kompatybilności. No i nie ma tych koszmarnych plików nagłówkowych do uzyskiwania (pseudo)modularności. Nie jest ślepą uliczką, jeśli nauczysz się Delphi, zrobisz kilka aplikacji, a później zaczniesz poznawać kolejny język.

Pytanie tylko, czy potrafimy myśleć i w C++ napiszemy tylko krytyczne części kodu. A przyspieszenie można uzyskać znaczne, sięgające nierzadko kilkuset procent.

Ja piszę o popularnych językach programowania.

Gdybyś na co dzień pisał w języku C++, nie miałbyś problemów z rozumieniem takich komunikatów.

Nie wiem, nie liczyłem. Chodziło mi o ideę :slight_smile:

C++ też jest starszy od Javy, a mimo to zdobyła popularność :slight_smile:

Java ma większą popularność i wsparcie, bo jest starsza i nie ma w tym nic dziwnego. Zobaczymy co będzie w przyszłości. Bo jak na razie, to na przestrzeni ostatnich lat Java traci popularność a C# zyskuje - zobacz na TIOBE.

Co do polityki M$ to nie wiem, o co Ci chodzi - przecież ostro promują C#, .NET i Visual Studio, wiele narzędzi dostępnych jest za darmo. Wersje na systemy inne niż Windows też są rozwijane.

Jasne, że przepisywanie kodu dla samej idei się nie opłaca. Ale coraz więcej nowszych projektów w nim powstaje, coraz więcej firm się specjalizuje w technologii .NET.

Piszesz o drobnych ulepszeniach. Dla kogoś, kto ich nigdy na oczy nie widział albo nie rozumie, to może i one są drobne.

Co ma C#, a czego nie ma Java:

  • więcej typów danych (decimal, wszystkie unsigned)

  • struktury

  • operacje bitowe na typach wyliczeniowych

  • tablice wielowymiarowe

  • klasy i metody częściowe

  • możliwość operowania na wskaźnikach

  • dowolne nazewnictwo plików i klas, dowolna liczba klas w pliku

  • właściwości jako element języka

  • switch mogący operować na większej liczbie typów danych (string i long)

  • using pozwalający na automatyczne zamykanie np. strumieni

  • delegaty i zdarzenia - prostsza implementacja Observera (w Javie klasa Publishera musi dziedziczyć po Observable, co przy możliwości dziedziczenia tylko z jednej klasy, jest dużym ograniczeniem)

  • przeładowanie operatorów

  • implementacja interfejsów explicit - nie ma problemu z identycznymi nazwami metod

  • wyrażenia lambda

  • metody rozszerzające

  • yield return

  • bardziej zwięzła składnia

To nie są drobne ulepszenia, to dużo więcej możliwości. Wszystko to zwiększa wygodę, wydajność bądź elastyczność.

Do tego dochodzi mniej zasobożerne IDE i mniej zasobożerne programy.

Więcej: http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java

Twoje zdanie miało aż taki wpływ na ten język? ;>

Moim zdaniem to, że język daje więcej możliwości jest rzeczą dobrą. A to, czy są one używane w odpowiedni sposób, zależy od programisty.

@somekind - Dobrze, dobrze, ulepszenia nie są drobne. :slight_smile: Nie chcę tu rozpętać kolejnej wojny C# kontra Java, bo obie technologie mają swoje mocniejsze i słabsze strony. Chciałem tylko nadmienić, że nadmiar udogodnień i swobody może być czasem postrzegany jako wada. Pewne rzeczy z tej listy wielokrotnie sugerowano jako kolejne udogodnienia Javy, ale wiele z nich po burzliwych dyskusjach zostało odrzucone (np. propertiesy czy pełne lambda-expressions). Problemem nie są często same ulepszenia per se, tylko jak ze sobą współpracują i jak wpływają (razem) na czytelność i rozumienie cudzego kodu. W C++ masz bardzo dużą elastyczność i można zrobić niemal wszystko zwłaszcza na template’ach, a mimo to ta swoboda często jest przyczyną poważnych problemów.

Co do popularności, to owszem, masz rację, ale popularność C# rośnie o wiele wolniej niż rosła popularność Javy w momencie gdy się pojawiła. C# nie jest obecny na rynku od wczoraj. BTW: Java na samym początku to było straszne /cenzura/, aż dziw bierze, że tak szybko zdobyła rynek.

Niemniej C# bardzo mocno przyczynia się też do rozwoju Javy. Konkurencja jest zawsze dobra. Myślę, że twórcy obydwu technologii uczą się od siebie nawzajem, a programisci dzięki temu dostają coraz lepsze środowiska.

Można prosić źródło tych rewelacji?

Kilkusetprocentowe różnice to owszem widziałem. W obie strony. I zawsze była to wina skaszanionej implementacji po którejś ze stron.

Przy dobrze napisanym dużym kodzie różnice najczęściej są niezauważalne. Nie ma żadnego powodu dla którego program w C#/Javie miałby być kilka razy wolniejszy niż odpowiednik w C lub C++ (prócz programisty idioty).

Apache vs Tomcat 6.x - praktycznie remis

H2 vs MySQL - tu Javowe H2 deklasuje MySQLa wydajnością

Jake vs Quake - implementacja w C++ dała tylko 20% więcej FPS.

Najwidoczniej mało jeszcze widziałeś.

Zaimplementujmy filtr medianowy o promieniu 3px (kwadrat 5x5), operujący na dwuwymiarowej tablicy 1000x1000. Ja napisze taki filtr w języku C++ a Ty w języku zarządzanym (C# lub Java) i porównamy sobie wyniki. Podejmiesz wyzwanie?

A jaki jest sens tworzyć kolejny microbenchmark, który testowałby właściwie tylko wektoryzację / rozwijanie pętli i proste operacje arytmetyczne? Takich microbenchmarków znajdziesz dużo na Great Language Shootout. Java nie odbiega od C++ w większości testów o więcej niż 30% (a w wielu różnica jest mniejsza).

Dodane 26.05.2009 (Wt) 14:26

Wiesz, tak dla hecy zaimplementowałem ten filtr medianowy. Niech Ci będzie :stuck_out_tongue:

Java:

import java.util.Arrays;



public class MedianFilter {



    private static int median(int[] array) {        

        Arrays.sort(array);

        return array[array.length / 2];                

    }



    private static void filter(int[][] input, int[][] output) {


        final int HEIGHT = input.length;

        final int WIDTH = input[0].length;

        final int RADIUS = 2;

        final int KERNEL_SIZE = (2 * RADIUS + 1);


        int[] kernel = new int[KERNEL_SIZE * KERNEL_SIZE];        


        for (int y = RADIUS; y < HEIGHT - RADIUS; y++) {

            for (int x = RADIUS; x < WIDTH - RADIUS; x++) {

                int kernelIndex = 0;

                for (int i = y - RADIUS; i <= y + RADIUS; i++) {

                    for (int j = x - RADIUS; j <= x + RADIUS; j++) {

                        kernel[kernelIndex++] = input[i][j];

                    }

                }

                output[y][x] = median(kernel);                                                                    

            }                

        }

    }



    public static void main(String[] args) {


        int[][] input = new int[1000][1000];

        int[][] output = new int[1000][1000];


        long start = System.nanoTime();


        for (int i = 0; i < 50; i++) {

            filter(input, output);

        }


        long end = System.nanoTime();

        System.out.printf("Elapsed time: %f ms\n", (end - start) / 1000000.0);            

    }


}

C:

#include

#include

#include



#define HEIGHT 1000

#define WIDTH 1000

#define RADIUS 2

#define KERNEL_SIZE (2 * RADIUS + 1)



int compare(const void* a, const void* b) {

	return *(int*) a - *(int*) b;

}



int median(int array[], int length) {        

    qsort(array, length, sizeof(int), &compare);

    return array[length / 2];                

}



void filter(int input[][WIDTH], int output[][WIDTH]) {


    int kernel[KERNEL_SIZE * KERNEL_SIZE];

    int x, y, i, j, kernelIndex;        


    for (y = RADIUS; y < HEIGHT - RADIUS; y++) {

        for (x = RADIUS; x < WIDTH - RADIUS; x++) {

            kernelIndex = 0;

            for (i = y - RADIUS; i <= y + RADIUS; i++) {

                for (j = x - RADIUS; j <= x + RADIUS; j++) {

                    kernel[kernelIndex++] = input[i][j];

                }

            }

            output[y][x] = median(kernel, KERNEL_SIZE * KERNEL_SIZE);                                                                    

        }                

    }   

}



int main() {


    int input[HEIGHT][WIDTH];

    int output[HEIGHT][WIDTH];


	struct timeval tv1;

    struct timeval tv2;


    int i, time;                                                     


    gettimeofday(&tv1, NULL);                        


    for (i = 0; i < 50; i++) {            

    	filter(input, output);                                           

    }   


    gettimeofday(&tv2, NULL);

    time = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec + 1000) % 1000;

    printf("Elapsed time: %d ms\n", time);        

    return 0;

}

C++ (właściwie nie do końca, ale przepisałem na C++ tylko fragment odpowiedzialny za sortowanie, bo on jest wąskim gardłem algorytmu):

#include

#include

#include

#include

using namespace std;



#define HEIGHT 1000

#define WIDTH 1000

#define RADIUS 2

#define KERNEL_SIZE (2 * RADIUS + 1)



int median(int array[], int length) {        

    sort(array, array + length);

    return array[length / 2];                

}



void filter(int input[][WIDTH], int output[][WIDTH]) {


    int kernel[KERNEL_SIZE * KERNEL_SIZE];

    int x, y, i, j, kernelIndex;        


    for (y = RADIUS; y < HEIGHT - RADIUS; y++) {

        for (x = RADIUS; x < WIDTH - RADIUS; x++) {

            kernelIndex = 0;

            for (i = y - RADIUS; i <= y + RADIUS; i++) {

                for (j = x - RADIUS; j <= x + RADIUS; j++) {

                    kernel[kernelIndex++] = input[i][j];

                }

            }

            output[y][x] = median(kernel, KERNEL_SIZE * KERNEL_SIZE);                                                                    

        }                

    }   

}



int main() {


    int input[HEIGHT][WIDTH];

    int output[HEIGHT][WIDTH];


	struct timeval tv1;

    struct timeval tv2;


    int i, time;                                                     


    gettimeofday(&tv1, NULL);                        


    for (i = 0; i < 50; i++) {            

    	filter(input, output);                                           

    }   


    gettimeofday(&tv2, NULL);

    time = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec + 1000) % 1000;

    printf("Elapsed time: %d ms\n", time);        

    return 0;

}

Wyniki na moim kompie z 3 pomiarów (AMD Athlon 3700+, 1GB RAM, jeden rdzeń)

Java (java -server Median):

  1. 18423 ms

  2. 17091 ms

  3. 18367 ms

C (gcc median.c -O2):

  1. > 60 s (nie chciało mi się dłużej czekać - jedna iteracja ~1200 ms)

C++: (g++ median.cpp -O2)

  1. 21423 ms

  2. 21892 ms

  3. 21708 ms

C++: (g++ median.cpp -march=i686 -m3dnow -fomit-frame-pointer -O3)

  1. 15796 ms

  2. 15704 ms

  3. 15387 ms

I jeszcze wersje softu, którymi kompilowałem:

java version “1.6.0_12”

Java SE Runtime Environment (build 1.6.0_12-b04)

Java HotSpot Client VM (build 11.2-b01, mixed mode, sharing)

gcc (GCC) 4.2.4

Copyright © 2007 Free Software Foundation, Inc.

Wynik: Java nieznacznie wygrała z C++ ten benchmark przy typowych ustawieniach kompilatora (-O2 jest szeroko używane), za to, zgodnie z tym, czego się spodziewałem nieznacznie (<15%) przegrała przy wykosmoszonych ustawieniach kompilatora C++ (ale to jest nie fair o tyle, że 99% softu - tj. głównie bibliotek nie kompiluje się pod konkretny procesor, a pod wspólny mianownik np. 486). Benchmark wliczał czas kompilacji potrzebny na HotSpot w Javie. Być może bawiąc się opcjami gcc dałoby się wycisnąć jeszcze kilka %.

Niemniej - GDZIE JEST TWOJE KILKASET PROCENT RÓŻNICY? Proszę o przenośny i zgodny ze standardem kod w C++, który policzy to zadanie na moim kompie w mniej niż 6s (50 iteracji) - bo kilkaset % zaczyna się dla mnie od 300%.

Nic z tego nie rozumie ;p staszny offtop się zrobił - wszystko praktycznie nie na temat , chciałbym porównać te 2 jeżyki Delphi, C++ ew. C#. Nie myśle pisać zadmnych gier tylko aplikacje pod Windows.

O, to jednak bierzesz C# pod uwagę? C# czy Java to mała różnica (przynajmniej na samym początku). Wkleiłem porównanie wydajności, które dla C# pewnie wypadłoby podobnie. Więc nie bierz wydajności pod uwagę. Delphi wydajnościowo wypadało zawsze nieznacznie gorzej niż C++, więc pewnie nie będzie dużych różnic między Delphi i C# w tej kwestii.

Dlaczego upierasz się tak przy wyborze między Delphi i C++?

No i fajnie.

Nie zastanowiło Cię, dlaczego wersja napisana w języku C, liczy tak długo?

Krytyczną częścią kodu, jest wyznaczenie mediany a co za tym idzie sortowanie. Wiadome jest, że czas sortowania jest zależny od rozkładu danych. Zastanowiłeś się co sortujesz?

Aby powyższe testy był miarodajne, powinieneś wypełnić tablicę źródłową danymi, jednakowymi dla każdego języka. Zmień także metodę sortowania, na sortowanie przez wstawianie (patrz kod w C++), jest szybsza dla małych tablic.

I miej świadomość, że nie należy definiować tak dużych tablic na stosie (ciało funkcji main), bo system może programowi tyle stosu nie przydzielić.

Poniżej poprawiona implementacja w języku C++. Przenieś to na Javę i powtórz testy.

Zauważ, że zmniejszyłem ilość iteracji do dziesięciu.

#include 

#include 

#include 


const int HEIGHT = 1000;

const int WIDTH = 1000;

const int RADIUS = 2;

const int KERNEL_SIZE = 2 * RADIUS + 1;


inline int median(int buffer[], int size)

{

  for (int i = 1; i < size; ++i) {

    int j = i - 1;

    int tmp = buffer[i];


    while((j >= 0) && (tmp < buffer[j])) {

      buffer[j + 1] = buffer[j--];

    }  

    buffer[j + 1] = tmp;

  }

	return buffer[size / 2];

} 


inline void filter(int input[][WIDTH], int output[][WIDTH]) 

{           

  int kernel[KERNEL_SIZE * KERNEL_SIZE];


  for (int y = RADIUS; y < HEIGHT - RADIUS; ++y) {

    for (int x = RADIUS; x < WIDTH - RADIUS; ++x) {

      int kernelIndex = 0;

      for (int i = y - RADIUS; i <= y + RADIUS; ++i) {

        for (int j = x - RADIUS; j <= x + RADIUS; ++j) {

          kernel[kernelIndex++] = input[i][j];

        }

      }

      output[y][x] = median(kernel, KERNEL_SIZE * KERNEL_SIZE);

    }               

  }   

}


int input[HEIGHT][WIDTH];

int output[HEIGHT][WIDTH];


int main() 

{                                                

  for (int y = 0; y < HEIGHT; ++y) {

    for (int x = 0; x < WIDTH; ++x) {

      input[y][x] = (x * x - x * x * x - y * y + y * y * y) & 255;

    }

  }


  clock_t start=clock();


  for (int i = 0; i < 10; ++i) {           

     filter(input, output);                                           

  }   


	clock_t stop=clock();

	std::cout << "Time: " << double(stop-start)/CLOCKS_PER_SEC * 1000 << " ms" << std::endl;


  return 0;

}

O Javie jest więcej książek, jest popularniejsza na uczelniach, jest do niej wiele narzędzi, dodatkowych bibliotek, wiele firm na niej pracuje. Microsoftowi będzie raczej trudno odebrać jej szybko rynek, więc mnie to nie dziwi :slight_smile:

Jeśli chcesz pisać tylko aplikacje pod Windows to C# jest najlepszym wyborem.

W miarę prosty, przejrzysta składnia, wiele gotowych kontrolek, daje ogromne możliwości, ma bardzo dobre środowisko za darmo: http://www.microsoft.com/express/vcsharp/Default.aspx i dokumentację: http://www.msdn.com/

@pebal -

  1. Co do C, to wiem, czemu tak się dzieje i nie… nie jest to błąd. Nie ma możliwości wykorzystać bibliotecznego qsort szybciej. Żeby było szybciej, trzeba go zaimplementować ręcznie dla intów. Nie chciało mi się :wink:

  2. Co do sortowania przez wstawianie, pewnie masz rację (choć przy 25 elementach nie byłbym taki pewien). Niemniej wszystkie 3 implementacje używały quicksorta, więc test był fair.

  3. Faktycznie powienienem był wypełnić tablicę losowymi danymi, ale jest problem z uzyskaniem takich samych danych w obu językach. Stąd tablice były wypełnione 0 (ok, niedopatrzenie - nie wyzerowałem tablic w C/C++, ale jak wyzerowałem - to nie zmieniło to czasów).

  4. Wypełnienie różnymi losowymi danymi daje dla 10 iteracji wyniki (w skrócie).

Java: ~13.0 s

C++ (-O2): ~9.8 s

C++ (-O3 -march=i686 -fomit-frame-pointer -m3dnow): ~7.5s

  1. inline nic tu nie zmienia - główny koszt jest wewnątrz sortowania, a nie wywołań funkcji, zresztą kompilator małe funkcje automatycznie inline’uje nawet jak nie ma specyfikatora inline.

Przy czym losowanie w C/C++ robiłem rand(), który jest “mniej losowy” niż java.util.Random, więc może to mieć wpływ na wyniki benchmarku.

Nadal nie ma moich upragnionych 300% różnicy. Do tego test testuje jedynie szybkość sortowania - wyciąganie jakichkolwiek wniosków z tak jednostronnego testu jest bez sensu, szczególnie że Java i C# w testach tego typu będą zawsze dostawały po d**ie za sprawdzanie zakresów tablic. Dopisz kod / skompiluj wersję C++ tak żeby sprawdzała indeksy tablic i wtedy zobaczymy. :stuck_out_tongue:

Dodane 26.05.2009 (Wt) 17:56

Sprawdziłem Twój kod i faktycznie, wstawianie jest szybsze od qsorta. Paradoksalnie jednak to wyrównało szanse (coś tego quicksorta w Javie pewnei mogliby poprawić):

C++ (-O2): 7833 ms, 7621 ms, 8032 ms

C++ (-O3 …): 6334 ms, 6954 ms, 6988 ms

Java: 8019 ms, 7855 ms, 8145 ms

:stuck_out_tongue:

A dlaczego nie użyłeś tego:

for (int y = 0; y < HEIGHT; ++y) {

    for (int x = 0; x < WIDTH; ++x) {

      input[y][x] = (x * x - x * x * x - y * y + y * y * y) & 255;

    }

  }

Miałbyś wtedy jednakowe dane.

?

Tego użyłem akurat w ostatnim teście (dopisane). Ale i tak nie zmienia wyników względem rand().

BTW: Jest jeszcze jedna taka kwestia dotycząca optymalizacji w Javie/C# - wiele możliwych optymalizacji w kompilatorze nie jest JESZCZE zaimplementowanych. I widać z wersji na wersje, że JVM i runtime .NET przyspieszają, średnio czasem nawet i po 10-30%. Natomiast kompilatory C++ od wielu lat stoją niemal w miejcu - bo tam już praktycznie wszystko, co się da zrobić, zostało zrobione.

Tu masz wyniki badań, które mogą przyspieszyć wykonywanie zwłaszcza takich benchmarków korzystających mocno z tablic: http://www.cs.umd.edu/~vibha/330/array-bounds.pdf. Z tego co wiem, nie weszły one jeszcze całkowicie do dostępnych implementacji Javy.

Swoją drogą jestem ciekaw, jak wypadłby benchmark, który testuje nie głównie dostępy do tablic, a wywołania metod wirtualnych oraz wywołania metod między modułami. Albo wydajność synchronizacji wątków (np. dostęp do bezpiecznych ze względu na wątki kolekcji).

Bardzo możliwe, że tu C++ dostałoby po d***ie, bo nie potrafi inline’ować wywołań metod pomiędzy modułami ani dynamicznie usuwać niepotrzebnych blokad. Ciekawe tylko, że prawie wszystki benchmarki na sieci to jakiś “number crunching” programikami na 30 linijek, a nie przykłady rzeczywistych sytuacji (gdzie b. często korzysta się z biblitek dynamicznie ładowanych, metod wirtualnych czy alokacji małych obiektów na stercie).

Na początku polecam nauczyć Ci się “Pythona”. Na 100% Ci się spodoba, potem przeskocz na C++, potem C# … ale w tym czasie, Delphi sobie całkowicie podaruj.