Страница: 1 |
Страница: 1 |
Вопрос: QuickSort
Добавлено: 03.09.06 09:29
Автор вопроса: CyRax | Web-сайт:
Написал реализацию QuickSort на Inline Assembler для BYTE, INTEGER/WORD и LONG/DWORD. Вот результаты тестов в сравнении с встроенной в PB8 процедурой Array Sort.
Тесты для массива из 524289 элементов на процессоре Celeron 433.
Тип BYTE
QuickSort - 0.33 sec; Array Sort - 1.04 sec
Тип INTEGER
QuickSort - 0.50 sec; Array Sort - 1.26 sec
Тип LONG
QuickSort - 0.50 sec; Array Sort - 1.21 sec
Тип BYTE
QuickSort - 0.27 sec; Array Sort - 1.10 sec
Тип INTEGER
QuickSort - 0.44 sec; Array Sort - 1.48 sec
Тип LONG
QuickSort - 0.48 sec; Array Sort - 1.26 sec
Потестируйте на скорость. В архиве исходники и скомпилированное приложение.
http://basicproduction.nm.ru/POWERBASIC/PBQSORTASM.rar
Ответы
Всего ответов: 12
Номер ответа: 1
Автор ответа:
SyavX
Вопросов: 25
Ответов: 149
Профиль | | #1
Добавлено: 03.09.06 13:51
Celeron 2.53 GHz
Тип BYTE
QuickSort - 0.094 sec; Array Sort - 0.344 sec
Тип INTEGER
QuickSort - 0.11 sec; Array Sort - 0.515 sec
Тип LONG
QuickSort - 0.172 sec; Array Sort - 0.484 sec
Тип BYTE
QuickSort - 0.078 sec; Array Sort - 0.36 sec
Тип INTEGER
QuickSort - 0.125 sec; Array Sort - 0.453 sec
Тип LONG
QuickSort - 0.141 sec; Array Sort - 0.484 sec
Тип BYTE
QuickSort - 0.079 sec; Array Sort - 0.375 sec
Тип INTEGER
QuickSort - 0.141 sec; Array Sort - 0.5 sec
Тип LONG
QuickSort - 0.188 sec; Array Sort - 0.516 sec
Номер ответа: 2
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #2
Добавлено: 03.09.06 17:25
SyavX,
спасибо. Вижу на более современном компьютере разрыв несколько больше чем на моём.
Номер ответа: 3
Автор ответа:
JMP
Вопросов: 6
Ответов: 171
Профиль | | #3
Добавлено: 04.09.06 07:08
Немножко поменял тест, использовал микросекундный таймер для более точного подсчета времени сортировки (TIMER более грубый) и вогнал процессы сортировки в реал тайм чтобы все было честно для всех в любое время.
#COMPILE EXE
#DIM ALL
'-----------------------
#INCLUDE "win32api.inc"
#INCLUDE "qsortasm.inc"
'-----------------------
FUNCTION PBMAIN
LOCAL hWnd AS DWORD
LOCAL sRes AS STRING
LOCAL qTimer AS QUAD
LOCAL T1 AS QUAD
LOCAL Counter AS LONG
LOCAL tmp AS LONG
 IALOG NEW 0, "Pleas wait...Comparison PB & CyRax sort method" _
,,, 190, 1 TO hWnd
 IALOG SHOW MODELESS hWnd
'BYTE -------------------CyRax-------------------
REDIM Test1(524288) AS BYTE
RANDOMIZE 1234567 ' will produce same random values for both method
FOR Counter=0 TO UBOUND(Test1)
Test1(Counter)=RND(1,255)
NEXT Counter
SetPriorityClass(GetCurrentProcess(), %REALTIME_PRIORITY_CLASS)
QueryPerformanceCounter(BYVAL VARPTR (T1))
QuickSort 1,1, VARPTR(Test1(0)),LBOUND(Test1),UBOUND(Test1)
QueryPerformanceCounter(BYVAL VARPTR (qTimer))
SetPriorityClass(GetCurrentProcess(), %NORMAL_PRIORITY_CLASS)
sRes="QuickSort BYTE="+FORMAT$((qTimer-T1)/1000000,"##.######" & " sec."
'BYTE -----------------PB------------------------
RANDOMIZE 1234567
FOR Counter=0 TO UBOUND(Test1)
Test1(Counter)=RND(1,255)
NEXT Counter
SetPriorityClass(GetCurrentProcess(), %REALTIME_PRIORITY_CLASS)
QueryPerformanceCounter(BYVAL VARPTR (T1))
ARRAY SORT Test1()
QueryPerformanceCounter(BYVAL VARPTR (qTimer))
SetPriorityClass(GetCurrentProcess(), %NORMAL_PRIORITY_CLASS)
sRes=sRes+$CRLF+"PBSort BYTE="+FORMAT$((qTimer-T1)/1000000,"##.######" & " sec."
'INTEGER -------------------CyRax-------------------
REDIM Test2(524288) AS INTEGER
RANDOMIZE 1234567
FOR Counter=0 TO UBOUND(Test2)
Test2(Counter)=RND(1,65535)
NEXT Counter
SetPriorityClass(GetCurrentProcess(), %REALTIME_PRIORITY_CLASS)
QueryPerformanceCounter(BYVAL VARPTR (T1))
QuickSort 2,1, VARPTR(Test2(0)),LBOUND(Test2),UBOUND(Test2)
QueryPerformanceCounter(BYVAL VARPTR (qTimer))
SetPriorityClass(GetCurrentProcess(), %NORMAL_PRIORITY_CLASS)
sRes=sRes+$CRLF+$CRLF+"QuickSort INTEGER="+FORMAT$((qTimer-T1)/1000000,"##.######" & " sec."
'INTEGER -----------------PB------------------------
RANDOMIZE 1234567
FOR Counter=0 TO UBOUND(Test2)
Test2(Counter)=RND(1,65535)
NEXT Counter
SetPriorityClass(GetCurrentProcess(), %REALTIME_PRIORITY_CLASS)
QueryPerformanceCounter(BYVAL VARPTR (T1))
ARRAY SORT Test2()
QueryPerformanceCounter(BYVAL VARPTR (qTimer))
SetPriorityClass(GetCurrentProcess(), %NORMAL_PRIORITY_CLASS)
sRes=sRes+$CRLF+"PBArray Sort INTEGER="+FORMAT$((qTimer-T1)/1000000,"##.######" & " sec."
'MsgBox Str$(Timer-T1) & " sec.",,"Array Sort INTEGER"
'LONG -------------------CyRax-------------------
REDIM Test4(524288) AS LONG
RANDOMIZE 1234567
FOR Counter=0 TO UBOUND(Test4)
Test4(Counter)=RND(-2000000,2000000)
NEXT Counter
SetPriorityClass(GetCurrentProcess(), %REALTIME_PRIORITY_CLASS)
QueryPerformanceCounter(BYVAL VARPTR (T1))
QuickSort 4,1, VARPTR(Test4(0)),LBOUND(Test4),UBOUND(Test4)
QueryPerformanceCounter(BYVAL VARPTR (qTimer))
SetPriorityClass(GetCurrentProcess(), %NORMAL_PRIORITY_CLASS)
sRes=sRes+$CRLF+$CRLF+"QuickSort LONG="+FORMAT$((qTimer-T1)/1000000,"##.######" & " sec."
'LONG -----------------PB------------------------
RANDOMIZE 1234567
FOR Counter=0 TO UBOUND(Test4)
Test4(Counter)=RND(-2000000,2000000)
NEXT Counter
SetPriorityClass(GetCurrentProcess(), %REALTIME_PRIORITY_CLASS)
QueryPerformanceCounter(BYVAL VARPTR (T1))
ARRAY SORT Test4()
QueryPerformanceCounter(BYVAL VARPTR (qTimer))
SetPriorityClass(GetCurrentProcess(), %NORMAL_PRIORITY_CLASS)
sRes=sRes+$CRLF+"PBArray Sort LONG="+FORMAT$((qTimer-T1)/1000000,"##.######" & " sec."
'------------------------------------------------
SendMessage (hWnd,%WM_SYSCOMMAND,%SC_CLOSE,0)
OPEN "ComparePB&CyRaxSortSpeed.txt" FOR OUTPUT AS #1
PRINT #1,"Result of sort speed comparison PB & CyRax"+ _
$CRLF+REPEAT$(40,"*"+$CRLF+$CRLF
PRINT #1, sRes+$CRLF+REPEAT$(40,"*"
CLOSE #1
? sRes,,"Result of sort speed comparison PB & CyRax"
END FUNCTION
реультат на дохлом ноуте Pent-II-450 +W98:
Test1:
QuickSort BYTE=0.343834 sec.
PBSort BYTE=1.088841 sec.
QuickSort INTEGER=0.426523 sec.
PBArray Sort INTEGER=1.431078 sec.
QuickSort LONG=0.494382 sec.
PBArray Sort LONG=1.393122 sec.
Test2:
QuickSort BYTE=0.345421 sec.
PBSort BYTE=1.085049 sec.
QuickSort INTEGER=0.426215 sec.
PBArray Sort INTEGER=1.431569 sec.
QuickSort LONG=0.493927 sec.
PBArray Sort LONG=1.393133 sec.
Класс ! Спасибо !!!
Номер ответа: 4
Автор ответа:
JMP
Вопросов: 6
Ответов: 171
Профиль | | #4
Добавлено: 04.09.06 07:13
А забыл, еще использовал одинаковый сид для генерации
одинаковых значений для обоих методох ПБ и CyRax, чтобы все было честно(одинаковые задачи) для обоих методох.
Еще раз спасибо, классная работа !
Номер ответа: 5
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #5
Добавлено: 04.09.06 08:11
Да, вот ещё для удобства ввёл константы
%ln_WORD=2
%ln_DWORD=4
%s_UNSIGNED=0
%s_SIGNED=1
Первые 3 для первого параметра, вторые 2 для второго.
JMP,
и тебе спасибо за более точное тестирование. Сейчас посмотрю что у меня получится.
Номер ответа: 6
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #6
Добавлено: 04.09.06 08:43
Ну в принципе отличий особых не заметил. Сотые доли секунд не принципиальны. Разницу вроде и так видно.
Номер ответа: 7
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #7
Добавлено: 04.09.06 10:18
Народ, что за прога, где качать, с чем хавать, как тестировать?
Номер ответа: 8
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #8
Добавлено: 04.09.06 17:33
На Pentium 4 - 1.6 Ггц.
QuickSoft Byte - 0.094
ArraySort Byte - 0.703
QuickSort Integer - 0.125
ArraySort Integer - 0.75
QuickSort long - 0.125
ArraySort long - 0.578
Номер ответа: 9
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #9
Добавлено: 04.09.06 17:38
CyRax - выложи исходник на PowerBASIC Forums\Source Code
Пусть знают, что мы тут тоже не щи лаптем хлебаем.. ))))))
Номер ответа: 10
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #10
Добавлено: 04.09.06 22:57
alex,
Сначала нужно полностью убедится что всё сортируется правильно. Если вдруг прокол, то будет потом стыдно. Да и со строками у меня пока не получается.
Может кто подкинет нормальный алгоритм сравнения двух строк?
Номер ответа: 11
Автор ответа:
JMP
Вопросов: 6
Ответов: 171
Профиль | | #11
Добавлено: 05.09.06 04:45
Так подойдет ?
#COMPILE EXE
#DIM ALL
#REGISTER NONE
FUNCTION PBMAIN () AS LONG
LOCAL str1 AS STRING : str1 = "QWERTYUIOP"
LOCAL str2 AS STRING : str2 = "QWERTYUIOP"
LOCAL lenStr1,dwRes AS DWORD
LOCAL addrStr1,addrStr2 AS DWORD
addrStr1=STRPTR(str1)
addrStr2=STRPTR(str2)
lenStr1=LEN(str1)
IF lenStr1<>0 THEN
! mov esi,addrStr1
! mov edi,addrStr2
! mov ecx,lenStr1
! inc ecx
! repe cmpsb ; exit if not equal. in ecx wrong position
! mov dwRes,ecx ; if both string equal then ecx=0
IF dwRes THEN
? "ifferent char at position"+STR$(lenStr1-dwRes+1)
ELSE
? "Strings is equal"
END IF
ELSE
? "Source string can't be empty"
END IF
END FUNCTION
Номер ответа: 12
Автор ответа:
JMP
Вопросов: 6
Ответов: 171
Профиль | | #12
Добавлено: 05.09.06 06:57
Э-э-э, блин, вставил не тот кусок, первая ассемблерная инструкция конечно же должна быть
! cld