Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Power Basic

Страница: 1 | 2 | 3 |

 

  Вопрос: Небольшой тест скорости PB7 vs VB6 Добавлено: 29.03.05 19:07  

Автор вопроса:  Macronix | Web-сайт: http://x250.net/ | ICQ: 170650558 
В данном примере VB работает быстрее почти в два раза.
Тестировал на трех машинах. Почему так получилось? Может я чего не заметил. Выложите, плиз, свои результаты.

Код для VB

Option Explicit

Const THREAD_BASE_PRIORITY_IDLE = -15
Const THREAD_BASE_PRIORITY_LOWRT = 15
Const THREAD_BASE_PRIORITY_MIN = -2
Const THREAD_BASE_PRIORITY_MAX = 2
Const THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN
Const THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX
Const THREAD_PRIORITY_BELOW_NORMAL = (THREAD_PRIORITY_LOWEST + 1)
Const THREAD_PRIORITY_ABOVE_NORMAL = (THREAD_PRIORITY_HIGHEST - 1)
Const THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE
Const THREAD_PRIORITY_NORMAL = 0
Const THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT
Const HIGH_PRIORITY_CLASS = &H80
Const IDLE_PRIORITY_CLASS = &H40
Const NORMAL_PRIORITY_CLASS = &H20
Const REALTIME_PRIORITY_CLASS = &H100

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
Private Declare Function SetPriorityClass Lib "kernel32" (ByVal hProcess As Long, ByVal dwPriorityClass As Long) As Long
Private Declare Function GetThreadPriority Lib "kernel32" (ByVal hThread As Long) As Long
Private Declare Function GetPriorityClass Lib "kernel32" (ByVal hProcess As Long) As Long
Private Declare Function GetCurrentThread Lib "kernel32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long

Private Sub Form_Load()

Dim lTickCount As Long
Dim hThread As Long
Dim hProcess As Long
Dim lTest As Long

'Set High Priority
hThread = GetCurrentThread: hProcess = GetCurrentProcess
SetThreadPriority hThread, THREAD_PRIORITY_TIME_CRITICAL
SetPriorityClass hProcess, REALTIME_PRIORITY_CLASS

'Test
lTickCount = GetTickCount + 5000
While GetTickCount < lTickCount
lTest = lTest + 1: Wend
MsgBox Str$(lTest) & "+"

End Sub



Код для PB

#COMPILE EXE
#REGISTER NONE
#DIM ALL
#INCLUDE "Win32Api.Inc"

FUNCTION WINMAIN (BYVAL hInstance     AS DWORD, _
                  BYVAL hPrevInstance AS DWORD, _
                  BYVAL lpCmdLine     AS ASCIIZ PTR, _
                  BYVAL iCmdShow      AS LONG) AS LONG

REGISTER lTest      AS LONG
REGISTER lTickCount AS LONG
LOCAL hThread       AS LONG
LOCAL hProcess      AS LONG

'Set High Priority
hThread = GetCurrentThread : hProcess = GetCurrentProcess
CALL SetThreadPriority (hThread, %THREAD_BASE_PRIORITY_LOWRT)
CALL SetPriorityClass (hProcess, %REALTIME_PRIORITY_CLASS)

'Test
lTickCount = GetTickCount + 5000
WHILE GetTickCount < lTickCount
INCR lTest: WEND
MSGBOX STR$(lTest) & "+"

END FUNCTION

Ответить

  Ответы Всего ответов: 44  

Номер ответа: 1
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #1 Добавлено: 29.03.05 20:47
В этом примере тестируется не скорость выполнения цикла, а время, необходимое ф-ции GetTickCount чтобы получить количество тиков. А GetTickCount ни к VB, ни к PB отношения не имеет.

Ответить

Номер ответа: 2
Автор ответа:
 Macronix



ICQ: 170650558 

Вопросов: 12
Ответов: 46
 Web-сайт: http://x250.net/
 Профиль | | #2
Добавлено: 29.03.05 20:57
Получается, в VB вызов функции GetTickCount проходит быстрее, чем в PB (у меня на PIII 1GHz получалось VB:134896602+, PB:75328922, то-есть, почти в два раза)

Ответить

Номер ответа: 3
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #3
Добавлено: 29.03.05 22:27
Незнаю как в PB но в VB вызов API происходит из рук вон медленно :(

Ответить

Номер ответа: 4
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #4 Добавлено: 29.03.05 22:49
А ты уверен, что VB-виртуальная машина в точности повторила твой код? Я не уверен. Зачастую бывает, что она переиначивает то, что ты написал, видя, что цикл пустой (бесполезный), т.к. результат вычисления нигде не используется.

Кроме того в PB коде столько хлама, что тормоза ещё те :(

Вот во что превратился твой цикл (РВ):

00401887  |> 8975 A8        /MOV DWORD PTR SS:[EBP-58],ESI
0040188A  |. DB45 A8        |FILD DWORD PTR SS:[EBP-58]
0040188D  |. BB 01000000    |MOV EBX,1
00401892  |. E8 790B0000    |CALL Test.00402410
00401897  |. FF15 E8414000  |CALL DWORD PTR DS:[<&KERNEL32.GetTickCo>; [GetTickCount
0040189D  |. BB 01000000    |MOV EBX,1
004018A2  |. E8 4E0B0000    |CALL Test.004023F5
004018A7  |. E8 7D070000    |CALL Test.00402029
004018AC  |. DED9           |FCOMPP
004018AE  |. DFE0           |FSTSW AX
004018B0  |. 9E             |SAHF
004018B1  |. 0F83 05000000  |JNB Test.004018BC
004018B7  |. FF45 80        |INC DWORD PTR SS:[EBP-80]
004018BA  |.^EB CB          \JMP SHORT Test.00401887


Кроме GetTickCount ещё вызывается три каких-то левых ф-ции CALL Test.00402029, CALL Test.004023F5, CALL Test.00402410. И ещё какого-то хрена операции с плавающей запятой... На хрена всё это тут? Для занятия места и пожирания времени, не иначе :)

Потому и проигрывает.
Даже сделал цикл ассемблерной вставкой - и то попытался запихать свои левые ф-ции. Вставил таки :( Хорошо хоть не в тело цикла.

004017FB  |. FF15 98414000  CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
00401801  |. 50             PUSH EAX
00401802  |. 8BDC           MOV EBX,ESP
00401804  |. 8B43 04        MOV EAX,DWORD PTR DS:[EBX+4]
00401807  |. E8 41090000    CALL Test.0040214D
0040180C  |. 58             POP EAX
0040180D  |. 83C4 04        ADD ESP,4
00401810  |. E8 070C0000    CALL Test.0040241C
00401815  |. 8985 74FFFFFF  MOV DWORD PTR SS:[EBP-8C],EAX
0040181B  |. C745 80 000000>MOV DWORD PTR SS:[EBP-80],0
00401822  |. 56             PUSH ESI
00401823  |. 8BB5 74FFFFFF  MOV ESI,DWORD PTR SS:[EBP-8C]
00401829  |. 57             PUSH EDI
0040182A  |. FFD6           CALL ESI
0040182C  |. 05 88130000    ADD EAX,1388
00401831  |. 8BD8           MOV EBX,EAX
00401833  |> 47             /INC EDI
00401834  |. FFD6           |CALL ESI
00401836  |. 3BC3           |CMP EAX,EBX
00401838  |.^0F8E F5FFFFFF  \JLE Test.00401833


Сам цикл - последние 4 строки. :)))

А результаты если интересно, такие:

PB-цикл:  128 553 612
VB-цикл:  245 556 998
asm-цикл: 701 543 869


Вот тебе и PB :(






Ответить

Номер ответа: 5
Автор ответа:
 alex



Вопросов: 84
Ответов: 453
 Профиль | | #5 Добавлено: 29.03.05 22:58
Согласен с cresta, никакого отношения к скорости работы эти исходники не имеют.

x-bond странно, но в VB исходнике GetTickCount
описана у тебя как:
Private Declare Function GetTickCount Lib "kernel32" () As Long

А в "Win32Api.Inc" GetTickCount описан как:

Declare Function GetTickCount Lib "KERNEL32.DLL" Alias "GetTickCount" () As Dword

Видишь, типы то разные возвращаются! Поэтому и кажется, что VB быстрее работает. Перепиши в PB декаларацию как:
Private Declare Function GetTickCount Lib "kernel32" () As Long

И увидишь, что время работы примеров почти одиноково.

На моем P2-400:

VB пример: 52855533+
PB пример: 55965070+

PowerBASIC работает немного быстрее.

Ответить

Номер ответа: 6
Автор ответа:
 alex



Вопросов: 84
Ответов: 453
 Профиль | | #6 Добавлено: 29.03.05 23:11
И вообще, на powerbasic.com тема скорости работы “VB app vs PB app” поднималась неоднократно, и в основном из-за ошибок перевода Long а Dword, очередной юзер заявлял что VB быстрее PB. Когда начинали проверять дотошнее, выяснялось, что VB в среднем работает от 100% до 300% медленнее, чем PB.

Ответить

Номер ответа: 7
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #7 Добавлено: 29.03.05 23:56
Действительно, с Long PB немножко обогнал VB, и до кучи ещё два примера:
306 131 481 - PB
247 752 992 - VB
717 515 664 - vc++
720 704 084 - asm

На Atlon XP 2200.

Ответить

Номер ответа: 8
Автор ответа:
 alex



Вопросов: 84
Ответов: 453
 Профиль | | #8 Добавлено: 30.03.05 00:44
И вообще, писать на PB в стиле Visual Basic это неправильно. PowerBASIC позволяет грамотно оптимизировать работу программы, если использовать его "родные" конструкции. А бездумное копирование кода из VB, сводит эту оптимизацию к нулю.
Например, если взять типичную конструкцию SELECT CASE. Можно написать ее как в стиле VB:
Select Case TestString  

Или в стиле PB:
Select Case As Const$ TestString  


Рвзницу в призводительности посмотрите на этом исходнике для PowerBASIC Console Compiler:

#Compile Exe
#Register All
Declare Function GetTickCount Lib "KERNEL32.DLL" Alias "GetTickCount" () As Long
Macro maxtest = 3000000

Function PBMain
 Local t As Long
 Local i As Long
 Local x As Long
 Local u As Long
 Local TestString As String
 t = gettickcount - t
 u = gettickcount
 Cursor Off
 Print "--------------------------------"
 Print "Start Select Case speed"
 Print "--------------------------------"
 Print "Please wait... "
 Print " "
 Print "Visual Basic style, speed: ";
      For i = 1 To maxtest
          TestString="Test Speed"
           Select Case    TestString
              Case "String1"
                     x=1
              Case "String2"
                     x=2
              Case "String3"
                     x=3
              Case "String4"
                     x=4
              Case "String5"
                     x=5
              Case "String6"
                     x=6
              Case "Test Speed"
                     x=7
          End Select
    Next i
    u = gettickcount - u
    Print   Format$(u)
'------------------------------------------
 Print " "
 Print "Power Basic style,  speed: ";
 t = gettickcount - t
 u = gettickcount
     For i = 1 To maxtest
      TestString="Test Speed"
      Select Case As Const$ TestString
            Case "String1"
                     x=1
              Case "String2"
                     x=2
              Case "String3"
                     x=3
              Case "String4"
                     x=4
              Case "String5"
                     x=5
              Case "String6"
                     x=6
              Case "Test Speed"
                     x=7
          End Select
    Next i
     u = gettickcount - u
    Print   Format$(u)
    Print "--------------------------------"
  WaitKey$
End Function  


На моем P2-400 разница просто чудовищная:

--------------------------------
Start Select Case speed
--------------------------------
Please wait...

Visual Basic style, speed: 21050

Power Basic style, speed: 3104
--------------------------------


Кострукция Select Case As Const$ работает на 678%
быстрее, чем обычный Select Case...
Есть над чем подумать

Ответить

Номер ответа: 9
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #9
Добавлено: 30.03.05 11:04

Select Case As Const$

 А у меня все Case без Const$. Если я переделаю проблем не будет?

Ответить

Номер ответа: 10
Автор ответа:
 Macronix



ICQ: 170650558 

Вопросов: 12
Ответов: 46
 Web-сайт: http://x250.net/
 Профиль | | #10
Добавлено: 30.03.05 13:13
Знал же, что LONG быстрее чем DWORD, а проверить декларацию в Win32Api.Inc не соизволил.

Вот мои результаты с LONG: (округленные до милионов)
PIII 1Ghz
VB - 136
PB - 124

PIV 1.8Ghz
VB - 126
PB - 153

Athlon 2000+
VB - 224
PB - 345

Интересно, Атлон явно лидирует, а 3 пенек все еще отстает. и еще VB на 4 пеньке показал худший результат, чем на P1GHz, странно...

Ответить

Номер ответа: 11
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #11
Добавлено: 30.03.05 13:22
x-bond,
 цикл While...Wend лучше не использовать если тебе нужна скорость. Для этого есть цикл For...Next.

Ответить

Номер ответа: 12
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #12
Добавлено: 30.03.05 13:31
 И вообще, подготовительная оптимизация в любом языке никогда не мешает. Чем меньше неизвестных в цикле, тем лучше.
 И неизвестные - это необязательно числа. Например UCase$ или LCase$ лучше вынести за цикл.
Собственно для этого и нужен ассемблер (а не как пиасал Морфеус - для написания скриптов :)), чтобы понимать суть происходящего.

 PowerBasic позволяет производить оптимизацию вплоть до инструкций процессора. Уровень VB - самый низкий, расчитанный для новичков.
 Полнота использования этого инструмена (PB) зависит только от твоих знаний.
 К примеру какие ты строки используешь в критических участках? Нужно ASCIIZ - они намного быстрее. И т.д. Вобщем хочешь писать на уровне VB - получишь и скорость уровня VB. Чудес не бывает.

Ответить

Номер ответа: 13
Автор ответа:
 Macronix



ICQ: 170650558 

Вопросов: 12
Ответов: 46
 Web-сайт: http://x250.net/
 Профиль | | #13
Добавлено: 30.03.05 14:15
CyRax, вот ты говоришь об оптимизации, а на твоем сайте в примерах сравнения VB vs PB в коде VB даже не объявленны переменные, и работают как Variant, естественно Васик будет сильно тормозить.
Советую обновить тесты.

Ответить

Номер ответа: 14
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #14
Добавлено: 30.03.05 15:15

VB vs PB в коде VB даже не объявленны переменные, и работают как Variant

 А в PB-шный ты заглядывал? Там тоже самый медленный целочисленный тип используется - Dword.
 Всё бралось по минимуму. Хочешь - сделай по максимуму и отошли мне. Я проверю правильность алгоритмов и выложу на сайте.

Ответить

Номер ответа: 15
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #15
Добавлено: 30.03.05 15:18
Да, только не забудь ассемблерный тест вставить. Надеюсь ассемблер знаешь?

Ответить

Страница: 1 | 2 | 3 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам