Где-то на форумах мне попадались жалобы на медленность работы стандартного sort из Visual C++ 6.0. Но вот довелось столкнуться с этим лично. Выяснилось, что если в сортируемом массиве есть много одинаковых элементов, то sort начинает очень сильно тормозить. Уж не знаю, то ли это недостаток алгоритма, то ли глюк реализации. Удалось мне придумать, как обойти этот недостаток и форсировать работу sort. Может это и изобретение велосипеда, но зато трехколесного Все иллюстрирует пример: Код (Text): #include "stdafx.h" #include <stdlib.h> #include <time.h> #define SIZE 400000 int n[SIZE]; int m[SIZE]; int xc=0; int compare_my( int *x, int *y ) { int i= *x-*y; if(i>0) return(1); if(i<0) return(-1); xc++; return( ((xc&1)<<1)-1); } int compare( int *x, int *y ) {return(*x-*y);} main() {int i; clock_t start, finish; for(i=0;i<SIZE;i++) m[i]=n[i]=rand()/(RAND_MAX/16); // 0<= m,n < 16 start = clock(); qsort( n, SIZE, sizeof(int), compare_my ); finish = clock(); double duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "Sorting with hint. Execution time= %2.2f seconds\n", duration ); start = clock(); qsort( &m[0], SIZE, sizeof(int), compare ); finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "Standart sorting. Execution time= %2.2f seconds\n", duration ); for(i=0;i<SIZE;i++) if(m[i]!=n[i]) { printf("Results are different!\n"); exit(1);} printf("Results identical!\n"); getchar(); } Вывод программы: Sorting with hint. Execution time= 0.11 seconds Standart sorting. Execution time= 14.69 seconds Results identical! В сотню раз быстрее сортируется. А при больших SIZE ускорение работы еще значительнее. P.S. Интересно, а под другими компиляторами этот трюк поможет?
power1# g++ -v Using built-in specs. Target: i386-undermydesk-freebsd Configured with: FreeBSD/i386 system compiler Thread model: posix gcc version 4.2.1 20070719 [FreeBSD] power1# g++ qsort.cpp power1# ./a.out Sorting with hint. Execution time= 0.09 seconds Standart sorting. Execution time= 0.02 seconds Results identical!
MSVC8.0: Sorting with hint. Execution time= 0.22 seconds Standart sorting. Execution time= 0.06 seconds Std C++ sorting. Execution time= 0.01 seconds Results identical! MSVC6.0: Sorting with hint. Execution time= 0.22 seconds Standart sorting. Execution time= 57.89 seconds Std C++ sorting. Execution time= 0.05 seconds Results identical! Почти наверняка это неудачный алгоритм сортировки в старой RTL На современных компиляторах этой проблемы нет А вообще лучше использовать std::sort из стандартной библиотеки С++ т.к. тогда компилятор может инлайнить функцию сравнения. ЗЫ: что же это за такой кривой VC6, где sort требует int (__cdecl *)(int *,int *) вместо int (__cdecl *)(const void *,const void *) ? Исходники: Код (Text): #include <stdlib.h> #include <stdio.h> #include <time.h> #include <algorithm> #define SIZE 800000 int n[SIZE]; int m[SIZE];int k[SIZE]; int xc=0; int compare_my( void *x, const void *y ) { int i= *(int *)x-*(int *)y; if(i>0) return(1); if(i<0) return(-1); xc++; return( ((xc&1)<<1)-1); } int compare( const void *x, const void *y ) {return(*(int *)x-*(int *)y);} void main() {int i; clock_t start, finish; for(i=0;i<SIZE;i++) m[i]=n[i]=k[i]=rand()/(RAND_MAX/16); // 0<= m,n < 16 start = clock(); qsort( n, SIZE, sizeof(int), compare_my ); finish = clock(); double duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "Sorting with hint. Execution time= %2.2f seconds\n", duration ); start = clock(); qsort( m, SIZE, sizeof(int), compare ); finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "Standart sorting. Execution time= %2.2f seconds\n", duration ); start = clock(); std::sort(k, k + SIZE); finish = clock(); duration = (double)(finish - start) / CLOCKS_PER_SEC; printf( "Std C++ sorting. Execution time= %2.2f seconds\n", duration ); for(i=0;i<SIZE;i++) if(m[i]!=n[i]) { printf("Results are different!\n"); exit(1);} for(i=0;i<SIZE;i++) if(m[i]!=k[i]) { printf("Results are different!\n"); exit(1);} printf("Results identical!\n"); getchar(); }