()
| 993 | }; |
| 994 | |
| 995 | const calculateFrameTimeStats = (): FrameTimeStats => { |
| 996 | if (frameTimestampCount < 2) { |
| 997 | return { |
| 998 | min: 0 as Milliseconds, |
| 999 | max: 0 as Milliseconds, |
| 1000 | avg: 0 as Milliseconds, |
| 1001 | p50: 0 as Milliseconds, |
| 1002 | p95: 0 as Milliseconds, |
| 1003 | p99: 0 as Milliseconds, |
| 1004 | }; |
| 1005 | } |
| 1006 | |
| 1007 | const startIndex = (frameTimestampIndex - frameTimestampCount + FRAME_BUFFER_SIZE) % FRAME_BUFFER_SIZE; |
| 1008 | |
| 1009 | const deltas = new Array<number>(frameTimestampCount - 1); |
| 1010 | let min = Number.POSITIVE_INFINITY; |
| 1011 | let max = Number.NEGATIVE_INFINITY; |
| 1012 | let sum = 0; |
| 1013 | |
| 1014 | for (let i = 1; i < frameTimestampCount; i++) { |
| 1015 | const prevIndex = (startIndex + i - 1) % FRAME_BUFFER_SIZE; |
| 1016 | const currIndex = (startIndex + i) % FRAME_BUFFER_SIZE; |
| 1017 | const delta = frameTimestamps[currIndex] - frameTimestamps[prevIndex]; |
| 1018 | deltas[i - 1] = delta; |
| 1019 | |
| 1020 | if (delta < min) min = delta; |
| 1021 | if (delta > max) max = delta; |
| 1022 | sum += delta; |
| 1023 | } |
| 1024 | |
| 1025 | const avg = sum / deltas.length; |
| 1026 | |
| 1027 | // Sort for percentile calculations |
| 1028 | deltas.sort((a, b) => a - b); |
| 1029 | |
| 1030 | const p50Index = Math.floor(deltas.length * 0.50); |
| 1031 | const p95Index = Math.floor(deltas.length * 0.95); |
| 1032 | const p99Index = Math.floor(deltas.length * 0.99); |
| 1033 | |
| 1034 | return { |
| 1035 | min: min as Milliseconds, |
| 1036 | max: max as Milliseconds, |
| 1037 | avg: avg as Milliseconds, |
| 1038 | p50: deltas[p50Index] as Milliseconds, |
| 1039 | p95: deltas[p95Index] as Milliseconds, |
| 1040 | p99: deltas[p99Index] as Milliseconds, |
| 1041 | }; |
| 1042 | }; |
| 1043 | |
| 1044 | const calculatePerformanceMetrics = (): PerformanceMetrics => { |
| 1045 | const fps = calculateExactFPS(); |
no outgoing calls
no test coverage detected