idlize

Форк
0
/
KoalaProfiler.ts 
190 строк · 6.1 Кб
1
/*
2
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15

16
import { int32 } from "@koalaui/compat"
17

18
/**
19
 * Adds statistics for constructing/disposing of the TreeNode instances.
20
 * It is disabled by default because collecting such data affects performance.
21
 */
22
const DEBUG_WITH_NODE_STATS = false
23

24
export class KoalaProfiler {
25
    private static readonly map = DEBUG_WITH_NODE_STATS
26
        ? new Map<int32, Set<Object>>()
27
        : undefined
28

29
    static nodeCreated(nodeType: int32, node: Object) {
30
        if (KoalaProfiler.map === undefined) return
31
        let set = KoalaProfiler.map!.get(nodeType)
32
        if (set === undefined) {
33
            set = new Set<Object>()
34
            KoalaProfiler.map!.set(nodeType, set)
35
        }
36
        set.add(node)
37
    }
38

39
    static nodeDisposed(nodeType: int32, node: Object) {
40
        if (KoalaProfiler.map === undefined) return
41
        let set = KoalaProfiler.map!.get(nodeType)
42
        if (set === undefined) throw new Error("node never existed")
43
        if (!set.delete(node)) console.log("node is already disposed")
44
    }
45

46
    public static counters: KoalaProfiler | undefined = undefined
47

48
    private invalidations = 0
49
    private computes = 0
50
    private builds = 0
51
    private nodes = 0
52
    private realDraws = 0
53
    private cachedDraws = 0
54
    private measures = 0
55
    private layouts = 0
56
    private frames = 0
57
    private lastTime = 0.0
58
    private lastFPS = 0
59
    private updateEnterTime = 0.0
60
    private updateExitTime = 0.0
61
    private updateTime = 0.0
62
    private buildEnterTime = 0.0
63
    private buildExitTime = 0.0
64
    private buildTime = 0.0
65
    private layoutEnterTime = 0.0
66
    private layoutExitTime = 0.0
67
    private layoutTime = 0.0
68
    private drawEnterTime = 0.0
69
    private drawExitTime = 0.0
70
    private drawTime = 0.0
71
    private updatableStates = 0
72
    private mutableStates = 0
73
    private computableValues = 0
74

75
    static enable() {
76
        KoalaProfiler.counters = new KoalaProfiler()
77
    }
78

79
    static disable() {
80
        KoalaProfiler.counters = undefined
81
    }
82

83
    static enabled(): boolean {
84
        return KoalaProfiler.counters != undefined
85
    }
86

87
    reset() {
88
        this.invalidations = 0
89
        this.computes = 0
90
        this.builds = 0
91
        this.nodes = 0
92
        this.realDraws = 0
93
        this.cachedDraws = 0
94
        this.layouts = 0
95
        this.measures = 0
96
        this.updateEnterTime = 0
97
        this.updateExitTime = 0
98
        this.updatableStates = 0
99
        this.mutableStates = 0
100
        this.computableValues = 0
101
    }
102

103
    report() {
104
        console.log(this.getReport())
105
    }
106

107
    getReport(): string {
108
        const updateTime = Math.round(1000 * (this.updateExitTime - this.updateEnterTime))
109
        const buildTime = Math.round(1000 * (this.buildExitTime - this.buildEnterTime))
110
        const layoutTime = Math.round(1000 * (this.layoutExitTime - this.layoutEnterTime))
111
        const drawTime = Math.round(1000 * (this.drawExitTime - this.drawEnterTime))
112
        if (this.updateTime < updateTime) this.updateTime = updateTime
113
        if (this.buildTime < buildTime) this.buildTime = buildTime
114
        if (this.layoutTime < layoutTime) this.layoutTime = layoutTime
115
        if (this.drawTime < drawTime) this.drawTime = drawTime
116

117
        // TODO: OHOS does not properly handle \n in template literals
118
        const array = Array.of<string>(
119
            `invalidations: ${this.invalidations}`,
120
            `modified states: ${this.mutableStates}/${this.updatableStates} + ${this.computableValues}`,
121
            `update states (mks): ${this.updateTime} / ${updateTime}`,
122
            `build root node (mks): ${this.buildTime} / ${buildTime}`,
123
            `layout view (mks): ${this.layoutTime} / ${layoutTime}`,
124
            `draw view (mks): ${this.drawTime} / ${drawTime}`,
125
            `computes: ${this.computes}`,
126
            `builds: ${this.builds}`,
127
            `nodes: ${this.nodes}`,
128
            `realDraws: ${this.realDraws}`,
129
            `cachedDraws: ${this.cachedDraws}`,
130
            `measures: ${this.measures}`,
131
            `layouts: ${this.layouts}`,
132
            `FPS: ${this.lastFPS}`,
133
        )
134
        KoalaProfiler.map?.forEach((set:Set<Object>, kind:int32) => {
135
            if (set.size > 0) array.push(kind + ":" + set.size)
136
        })
137
        return array.join("\n")
138
    }
139

140
    invalidation() { this.invalidations++ }
141
    compute() { this.computes++ }
142
    build() { this.builds++ }
143
    node() { this.nodes++ }
144
    realDraw() { this.realDraws++ }
145
    cachedDraw() { this.cachedDraws++ }
146
    layout() {  this.layouts++ }
147
    measure() { this.measures++ }
148
    frame(ms: number) {
149
        if (ms - this.lastTime <= 1000) {
150
            this.frames++
151
        } else {
152
            this.lastFPS = Math.round(this.frames * 1000 / (ms - this.lastTime)) as int32
153
            this.frames = 1
154
            this.lastTime = ms
155
        }
156
    }
157
    buildRootEnter() {
158
        this.buildEnterTime = Date.now()
159
    }
160
    buildRootExit() {
161
        this.buildExitTime = Date.now()
162
    }
163
    layoutEnter() {
164
        this.layoutEnterTime = Date.now()
165
    }
166
    layoutExit() {
167
        this.layoutExitTime = Date.now()
168
    }
169
    drawEnter() {
170
        this.drawEnterTime = Date.now()
171
    }
172
    drawExit() {
173
        this.drawExitTime = Date.now()
174
    }
175
    updateSnapshotEnter() {
176
        this.updateEnterTime = Date.now()
177
    }
178
    updateSnapshotExit() {
179
        this.updateExitTime = Date.now()
180
    }
181
    updateSnapshot(modified: int32, all?: int32) {
182
        if (all === undefined) {
183
            this.computableValues = modified - this.mutableStates
184

185
        } else {
186
            this.mutableStates = modified
187
            this.updatableStates = all
188
        }
189
    }
190
}
191

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.