Почему
реальный, а потому что он считает реальное количество ФПС, а не гипотетическое.
Просматривая некоторые исходники, я заметил, что есть определенная тенденция
считать предполагаемое, а не фактическое количество кадров. Такой подход,
конечно, дает возможность наблюдать значение ФПС сразу после запуска, но нам
ведь важно настоящее значение, а не предполагаемое (надеюсь что так). Кратко о разнице в подходах (назову их
расчетным и подсчетным). Расчетный: Предполагаемое
количество считается исходя из времени обработки кадра. Зная это время, мы
можем определить количество кадров, которое у нас получится за больший
промежуток. Подсчетный: считается
тупо подсчетом кадров за отрезок времени. В чем недостатки расчетного метода: в
связи с многозадачностью современных ОС, из-за параллельных процессов время от
начала до завершения одного процесса будет разным, даже если выполняться будет
одинаковая задача. Из-за этого происходят определенные колебания расчетного
значения. Плюс получаемое значение можно отнести только к данному кадру, а для
другого кадра, оно будет уже другим, что не дает общей картины производительности. Плюс этого метода один –
расчетное значение можно получить уже после первого кадра. Недостаток
подсчетного метода в том, что мы можем узнать количество ФПС только после
какого-то промежутка времени. Вот пример с
классом счетчика ФПС: Strict Local bExit% = False Const fBaseFPS# = 50 Const cTimeDelta% = 1000/fBaseFPS '1000
- milisec in second / fps Local fps:TFPSCounter = New TFPSCounter Global
fSpeedMul# = 1; Graphics800 , 600 , 0 , fBaseFPS WhileNot bExit bExit
= KeyDown(KEY_ESCAPE) | AppTerminate() Local startTime = MilliSecs(); fps.start() DrawScene() 'draw info DrawText"FPS: " + round(fps.fps,1) , 8 , 8 DrawText"Min/Max: " + round(fps.fps_min,1) +"/" + round(fps.fps_max,1), 100, 8 DrawText"Average: " + round(fps.fps_average,3), 300, 8 'animate scene UpdateScene() 'fps.finish() Flip -1 'by Graphics refresh rate fps.finish() Wend Global x#=0, y#=300 Function UpdateScene() x
:+ 0.5 * fSpeedMul If x > GraphicsWidth() Then x = 0 'Delay(Rand(1,30)) EndFunction Function DrawScene() Cls DrawOval(x,y, 50, 50) EndFunction End Type TFPSCounter Field _fps_start# Field _fps_count# Field _avfps_start# Field _fps_average_count# Field fps# Field fps_average# Field fps_min# = 1000 Field fps_max# = 0 Method Start() Local ms# = MilliSecs() If _fps_start = 0Then _fps_start = ms If _avfps_start = 0Then _avfps_start = ms EndMethod Method Finish() Local millis# = MilliSecs() Local time# = millis - _fps_start _fps_count
:+ 1 If time > 1000 fps
= _fps_count*1000/time If fps < fps_min Then fps_min = fps If fps > fps_max Then fps_max = fps _fps_start
= 0 _fps_count
= 0 EndIf _fps_average_count
:+ 1 time
= millis - _avfps_start If time > 1000 fps_average
= _fps_average_count * 1000 / time EndIf EndMethod EndType Function Round$(value#, nDecimals%=2) Local str$ = value Local pos% = Instr(str , ".") If nDecimals > 0 str
= str[..pos + nDecimals] Else str
= str[..pos - 1] EndIf Return str EndFunction |
Комментарии к коду: Можно поиграть с
задержкой в UpdateScene. Дополнена функция
форматированного вывода плавающих чисел Round$. И еще внимание на положение вызова метода Finish
класса счетчика в коде. Если его поставить там, где он закомментирован (сразу после
апдейта сцены), то количество кадров странным образом считается на 1 больше. А
дело в том, что если его ставить до синхронизации (Flip -1), то получится, что последний кадр в отрезке времени
посчитается до завершения самого отрезка времени. Поэтому надо ставить вызов fps.finish() после синхронизации, чтобы
и временные интервалы и количество кадров считались правильно.
|