]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/src/perf/Accumulator.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / src / perf / Accumulator.js
CommitLineData
6527f429
DM
1/**\r
2 * @private\r
3 */\r
4Ext.define('Ext.perf.Accumulator', function () {\r
5 var currentFrame = null,\r
6 khrome = Ext.global['chrome'], // jshint ignore:line\r
7 formatTpl,\r
8 // lazy init on first request for timestamp (avoids infobar in IE until needed)\r
9 // Also avoids kicking off Chrome's microsecond timer until first needed\r
10 getTimestamp = function () {\r
11 getTimestamp = Ext.now;\r
12 \r
13 var interval, toolbox;\r
14\r
15 // If Chrome is started with the --enable-benchmarking switch\r
16 if (Ext.isChrome && khrome && khrome.Interval) {\r
17 interval = new khrome.Interval();\r
18 interval.start();\r
19 getTimestamp = function () {\r
20 return interval.microseconds() / 1000;\r
21 };\r
22 } else if (window.ActiveXObject) {\r
23 try {\r
24 // the above technique is not very accurate for small intervals...\r
25 toolbox = new ActiveXObject('SenchaToolbox.Toolbox'); // jshint ignore:line\r
26 Ext.senchaToolbox = toolbox; // export for other uses\r
27 getTimestamp = function () {\r
28 return toolbox.milliseconds;\r
29 };\r
30 } catch (e) {\r
31 // ignore\r
32 }\r
33 }\r
34\r
35 Ext.perf.getTimestamp = Ext.perf.Accumulator.getTimestamp = getTimestamp;\r
36 return getTimestamp();\r
37 };\r
38\r
39 function adjustSet (set, time) {\r
40 set.sum += time;\r
41 set.min = Math.min(set.min, time);\r
42 set.max = Math.max(set.max, time);\r
43 }\r
44\r
45 function leaveFrame (time) {\r
46 var totalTime = time ? time : (getTimestamp() - this.time), // do this first\r
47 me = this, // me = frame\r
48 accum = me.accum;\r
49\r
50 ++accum.count;\r
51 if (! --accum.depth) {\r
52 adjustSet(accum.total, totalTime);\r
53 }\r
54 adjustSet(accum.pure, totalTime - me.childTime);\r
55\r
56 currentFrame = me.parent;\r
57 if (currentFrame) {\r
58 ++currentFrame.accum.childCount;\r
59 currentFrame.childTime += totalTime;\r
60 }\r
61 }\r
62\r
63 function makeSet () {\r
64 return {\r
65 min: Number.MAX_VALUE,\r
66 max: 0,\r
67 sum: 0\r
68 };\r
69 }\r
70\r
71 function makeTap (me, fn) {\r
72 return function () {\r
73 var frame = me.enter(),\r
74 ret = fn.apply(this, arguments);\r
75\r
76 frame.leave();\r
77 return ret;\r
78 };\r
79 }\r
80\r
81 function setToJSON (count, childCount, calibration, set) {\r
82 var data = {\r
83 avg: 0,\r
84 min: set.min,\r
85 max: set.max,\r
86 sum: 0\r
87 };\r
88\r
89 if (count) {\r
90 calibration = calibration || 0;\r
91 data.sum = set.sum - childCount * calibration;\r
92 data.avg = data.sum / count;\r
93 // min and max cannot be easily corrected since we don't know the number of\r
94 // child calls for them.\r
95 }\r
96\r
97 return data;\r
98 }\r
99\r
100 return {\r
101 requires: [\r
102 'Ext.XTemplate',\r
103 'Ext.ClassManager'\r
104 ],\r
105\r
106 constructor: function (name) {\r
107 var me = this;\r
108\r
109 me.count = me.childCount = me.depth = me.maxDepth = 0;\r
110 me.pure = makeSet();\r
111 me.total = makeSet();\r
112 me.name = name;\r
113 },\r
114\r
115 statics: {\r
116 getTimestamp: getTimestamp\r
117 },\r
118\r
119 format: function (calibration) {\r
120 if (!formatTpl) {\r
121 formatTpl = new Ext.XTemplate([\r
122 '{name} - {count} call(s)',\r
123 '<tpl if="count">',\r
124 '<tpl if="childCount">',\r
125 ' ({childCount} children)',\r
126 '</tpl>',\r
127 '<tpl if="depth - 1">',\r
128 ' ({depth} deep)',\r
129 '</tpl>',\r
130 '<tpl for="times">',\r
131 ', {type}: {[this.time(values.sum)]} msec (',\r
132 //'min={[this.time(values.min)]}, ',\r
133 'avg={[this.time(values.sum / parent.count)]}',\r
134 //', max={[this.time(values.max)]}',\r
135 ')',\r
136 '</tpl>',\r
137 '</tpl>'\r
138 ].join(''), {\r
139 time: function (t) {\r
140 return Math.round(t * 100) / 100;\r
141 }\r
142 });\r
143 }\r
144\r
145 var data = this.getData(calibration);\r
146 data.name = this.name;\r
147 data.pure.type = 'Pure';\r
148 data.total.type = 'Total';\r
149 data.times = [data.pure, data.total];\r
150 return formatTpl.apply(data);\r
151 },\r
152\r
153 getData: function (calibration) {\r
154 var me = this;\r
155\r
156 return {\r
157 count: me.count,\r
158 childCount: me.childCount,\r
159 depth: me.maxDepth,\r
160 pure: setToJSON(me.count, me.childCount, calibration, me.pure),\r
161 total: setToJSON(me.count, me.childCount, calibration, me.total)\r
162 };\r
163 },\r
164\r
165 enter: function () {\r
166 var me = this,\r
167 frame = {\r
168 accum: me,\r
169 leave: leaveFrame,\r
170 childTime: 0,\r
171 parent: currentFrame\r
172 };\r
173\r
174 ++me.depth;\r
175 if (me.maxDepth < me.depth) {\r
176 me.maxDepth = me.depth;\r
177 }\r
178\r
179 currentFrame = frame;\r
180 frame.time = getTimestamp(); // do this last\r
181 return frame;\r
182 },\r
183\r
184 monitor: function (fn, scope, args) {\r
185 var frame = this.enter();\r
186 if (args) {\r
187 fn.apply(scope, args);\r
188 } else {\r
189 fn.call(scope);\r
190 }\r
191 frame.leave();\r
192 },\r
193\r
194 report: function () {\r
195 Ext.log(this.format());\r
196 },\r
197\r
198 tap: function (className, methodName) {\r
199 var me = this,\r
200 methods = typeof methodName === 'string' ? [methodName] : methodName,\r
201 klass, statik, i, parts, length, name, src,\r
202 tapFunc;\r
203\r
204 tapFunc = function(){\r
205 if (typeof className === 'string') {\r
206 klass = Ext.global;\r
207 parts = className.split('.');\r
208 for (i = 0, length = parts.length; i < length; ++i) {\r
209 klass = klass[parts[i]];\r
210 }\r
211 } else {\r
212 klass = className;\r
213 }\r
214\r
215 for (i = 0, length = methods.length; i < length; ++i) {\r
216 name = methods[i];\r
217 statik = name.charAt(0) === '!';\r
218\r
219 if (statik) {\r
220 name = name.substring(1);\r
221 } else {\r
222 statik = !(name in klass.prototype);\r
223 }\r
224\r
225 src = statik ? klass : klass.prototype;\r
226 src[name] = makeTap(me, src[name]);\r
227 }\r
228 };\r
229\r
230 Ext.ClassManager.onCreated(tapFunc, me, className);\r
231\r
232 return me;\r
233 }\r
234 };\r
235},\r
236function () {\r
237 Ext.perf.getTimestamp = this.getTimestamp;\r
238});\r