Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
75f49fcd
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
75f49fcd
编写于
8月 22, 2018
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
perf - fix loader stats
上级
6ec49533
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
122 addition
and
198 deletion
+122
-198
src/typings/require.d.ts
src/typings/require.d.ts
+24
-1
src/vs/workbench/parts/performance/electron-browser/actions.ts
...s/workbench/parts/performance/electron-browser/actions.ts
+98
-197
未找到文件。
src/typings/require.d.ts
浏览文件 @
75f49fcd
...
...
@@ -3,6 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare
const
enum
LoaderEventType
{
LoaderAvailable
=
1
,
BeginLoadingScript
=
10
,
EndLoadingScriptOK
=
11
,
EndLoadingScriptError
=
12
,
BeginInvokeFactory
=
21
,
EndInvokeFactory
=
22
,
NodeBeginEvaluatingScript
=
31
,
NodeEndEvaluatingScript
=
32
,
NodeBeginNativeRequire
=
33
,
NodeEndNativeRequire
=
34
}
declare
class
LoaderEvent
{
readonly
type
:
LoaderEventType
;
readonly
timestamp
:
number
;
readonly
detail
:
string
;
}
declare
var
define
:
{
(
moduleName
:
string
,
dependencies
:
string
[],
callback
:
(...
args
:
any
[])
=>
any
):
any
;
...
...
@@ -20,4 +42,5 @@ declare var require: {
config
(
data
:
any
):
any
;
onError
:
Function
;
__$__nodeRequire
<
T
>
(
moduleName
:
string
):
T
;
};
\ No newline at end of file
getStats
():
ReadonlyArray
<
LoaderEvent
>
};
src/vs/workbench/parts/performance/electron-browser/actions.ts
浏览文件 @
75f49fcd
...
...
@@ -23,30 +23,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
import
{
IWorkbenchActionRegistry
,
Extensions
}
from
'
vs/workbench/common/actions
'
;
import
{
SyncActionDescriptor
}
from
'
vs/platform/actions/common/actions
'
;
import
{
forEach
}
from
'
vs/base/common/collections
'
;
/* Copied from loader.ts */
enum
LoaderEventType
{
LoaderAvailable
=
1
,
BeginLoadingScript
=
10
,
EndLoadingScriptOK
=
11
,
EndLoadingScriptError
=
12
,
BeginInvokeFactory
=
21
,
EndInvokeFactory
=
22
,
NodeBeginEvaluatingScript
=
31
,
NodeEndEvaluatingScript
=
32
,
NodeBeginNativeRequire
=
33
,
NodeEndNativeRequire
=
34
}
interface
ILoaderEvent
{
type
:
LoaderEventType
;
timestamp
:
number
;
detail
:
string
;
}
import
{
mergeSort
}
from
'
vs/base/common/arrays
'
;
class
Info
{
...
...
@@ -75,6 +52,95 @@ class Info {
private
constructor
(
readonly
duration
:
number
,
readonly
process
:
string
,
readonly
info
:
string
|
boolean
=
''
)
{
}
}
class
LoaderStat
{
static
getLoaderStats
()
{
let
seq
=
1
;
const
amdLoad
=
new
Map
<
string
,
LoaderStat
>
();
const
amdInvoke
=
new
Map
<
string
,
LoaderStat
>
();
const
nodeRequire
=
new
Map
<
string
,
LoaderStat
>
();
const
nodeEval
=
new
Map
<
string
,
LoaderStat
>
();
function
mark
(
map
:
Map
<
string
,
LoaderStat
>
,
stat
:
LoaderEvent
)
{
if
(
map
.
has
(
stat
.
detail
))
{
// console.warn('BAD events, DOUBLE start', stat);
// map.delete(stat.detail);
return
;
}
map
.
set
(
stat
.
detail
,
new
LoaderStat
(
-
stat
.
timestamp
,
seq
++
));
}
function
diff
(
map
:
Map
<
string
,
LoaderStat
>
,
stat
:
LoaderEvent
)
{
let
obj
=
map
.
get
(
stat
.
detail
);
if
(
!
obj
)
{
// console.warn('BAD events, end WITHOUT start', stat);
// map.delete(stat.detail);
return
;
}
if
(
obj
.
duration
>=
0
)
{
// console.warn('BAD events, DOUBLE end', stat);
// map.delete(stat.detail);
return
;
}
obj
.
duration
=
(
obj
.
duration
+
stat
.
timestamp
);
}
const
stats
=
mergeSort
(
require
.
getStats
().
slice
(
0
),
(
a
,
b
)
=>
a
.
timestamp
-
b
.
timestamp
);
for
(
const
stat
of
stats
)
{
switch
(
stat
.
type
)
{
case
LoaderEventType
.
BeginLoadingScript
:
mark
(
amdLoad
,
stat
);
break
;
case
LoaderEventType
.
EndLoadingScriptOK
:
case
LoaderEventType
.
EndLoadingScriptError
:
diff
(
amdLoad
,
stat
);
break
;
case
LoaderEventType
.
BeginInvokeFactory
:
mark
(
amdInvoke
,
stat
);
break
;
case
LoaderEventType
.
EndInvokeFactory
:
diff
(
amdInvoke
,
stat
);
break
;
case
LoaderEventType
.
NodeBeginNativeRequire
:
mark
(
nodeRequire
,
stat
);
break
;
case
LoaderEventType
.
NodeEndNativeRequire
:
diff
(
nodeRequire
,
stat
);
break
;
case
LoaderEventType
.
NodeBeginEvaluatingScript
:
mark
(
nodeEval
,
stat
);
break
;
case
LoaderEventType
.
NodeEndEvaluatingScript
:
diff
(
nodeEval
,
stat
);
break
;
}
}
function
toObject
(
map
:
Map
<
string
,
any
>
):
{
[
name
:
string
]:
any
}
{
const
result
=
Object
.
create
(
null
);
map
.
forEach
((
value
,
index
)
=>
result
[
index
]
=
value
);
return
result
;
}
let
nodeRequireTotal
=
0
;
nodeRequire
.
forEach
(
value
=>
nodeRequireTotal
+=
value
.
duration
);
return
{
amdLoad
:
toObject
(
amdLoad
),
amdInvoke
:
toObject
(
amdInvoke
),
nodeRequire
:
toObject
(
nodeRequire
),
nodeEval
:
toObject
(
nodeEval
),
nodeRequireTotal
};
}
constructor
(
public
duration
:
number
,
public
seq
:
number
)
{
}
}
export
class
ShowStartupPerformance
extends
Action
{
...
...
@@ -114,19 +180,15 @@ export class ShowStartupPerformance extends Action {
console
.
log
(
`Screen Reader Active:
${
metrics
.
hasAccessibilitySupport
}
`
);
console
.
log
(
`Empty Workspace:
${
metrics
.
emptyWorkbench
}
`
);
let
nodeModuleLoadTime
:
number
;
if
(
this
.
environmentService
.
performance
)
{
const
nodeModuleTimes
=
this
.
analyzeNodeModulesLoadTimes
();
nodeModuleLoadTime
=
nodeModuleTimes
.
duration
;
}
cons
ole
.
table
(
Info
.
getTimerInfo
(
metrics
,
nodeModuleLoadTime
)
);
cons
t
loaderStats
=
this
.
environmentService
.
performance
&&
LoaderStat
.
getLoaderStats
(
);
if
(
this
.
environmentService
.
performance
)
{
const
data
=
this
.
analyzeLoaderStats
();
for
(
let
type
in
data
)
{
console
.
groupCollapsed
(
`Loader:
${
type
}
`
);
console
.
table
(
data
[
type
]);
console
.
table
(
Info
.
getTimerInfo
(
metrics
,
loaderStats
&&
loaderStats
.
nodeRequireTotal
));
if
(
loaderStats
)
{
for
(
const
key
in
loaderStats
)
{
console
.
groupCollapsed
(
`Loader:
${
key
}
`
);
console
.
table
(
loaderStats
[
key
]);
console
.
groupEnd
();
}
}
...
...
@@ -157,151 +219,6 @@ export class ShowStartupPerformance extends Action {
return
TPromise
.
as
(
true
);
}
private
analyzeNodeModulesLoadTimes
():
{
table
:
any
[],
duration
:
number
}
{
const
stats
=
<
ILoaderEvent
[]
>
(
<
any
>
require
).
getStats
();
const
result
=
[];
let
total
=
0
;
for
(
let
i
=
0
,
len
=
stats
.
length
;
i
<
len
;
i
++
)
{
if
(
stats
[
i
].
type
===
LoaderEventType
.
NodeEndNativeRequire
)
{
if
(
stats
[
i
-
1
].
type
===
LoaderEventType
.
NodeBeginNativeRequire
&&
stats
[
i
-
1
].
detail
===
stats
[
i
].
detail
)
{
const
entry
:
any
=
{};
const
dur
=
(
stats
[
i
].
timestamp
-
stats
[
i
-
1
].
timestamp
);
entry
[
'
Event
'
]
=
'
nodeRequire
'
+
stats
[
i
].
detail
;
entry
[
'
Took (ms)
'
]
=
dur
.
toFixed
(
2
);
total
+=
dur
;
entry
[
'
Start (ms)
'
]
=
'
**
'
+
stats
[
i
-
1
].
timestamp
.
toFixed
(
2
);
entry
[
'
End (ms)
'
]
=
'
**
'
+
stats
[
i
-
1
].
timestamp
.
toFixed
(
2
);
result
.
push
(
entry
);
}
}
}
if
(
total
>
0
)
{
result
.
push
({
Event
:
'
------------------------------------------------------
'
});
const
entry
:
any
=
{};
entry
[
'
Event
'
]
=
'
[renderer] total require() node_modules
'
;
entry
[
'
Took (ms)
'
]
=
total
.
toFixed
(
2
);
entry
[
'
Start (ms)
'
]
=
'
**
'
;
entry
[
'
End (ms)
'
]
=
'
**
'
;
result
.
push
(
entry
);
}
return
{
table
:
result
,
duration
:
Math
.
round
(
total
)
};
}
private
analyzeLoaderStats
():
{
[
type
:
string
]:
any
[]
}
{
const
stats
=
<
ILoaderEvent
[]
>
(
<
any
>
require
).
getStats
().
slice
(
0
).
sort
((
a
:
ILoaderEvent
,
b
:
ILoaderEvent
)
=>
{
if
(
a
.
detail
<
b
.
detail
)
{
return
-
1
;
}
else
if
(
a
.
detail
>
b
.
detail
)
{
return
1
;
}
else
if
(
a
.
type
<
b
.
type
)
{
return
-
1
;
}
else
if
(
a
.
type
>
b
.
type
)
{
return
1
;
}
else
{
return
0
;
}
});
class
Tick
{
readonly
duration
:
number
;
readonly
detail
:
string
;
constructor
(
private
readonly
start
:
ILoaderEvent
,
private
readonly
end
:
ILoaderEvent
)
{
console
.
assert
(
start
.
detail
===
end
.
detail
);
this
.
duration
=
this
.
end
.
timestamp
-
this
.
start
.
timestamp
;
this
.
detail
=
start
.
detail
;
}
toTableObject
()
{
return
{
[
'
Path
'
]:
this
.
start
.
detail
,
[
'
Took (ms)
'
]:
this
.
duration
.
toFixed
(
2
),
// ['Start (ms)']: this.start.timestamp,
// ['End (ms)']: this.end.timestamp
};
}
static
compareUsingStartTimestamp
(
a
:
Tick
,
b
:
Tick
):
number
{
if
(
a
.
start
.
timestamp
<
b
.
start
.
timestamp
)
{
return
-
1
;
}
else
if
(
a
.
start
.
timestamp
>
b
.
start
.
timestamp
)
{
return
1
;
}
else
{
return
0
;
}
}
}
const
ticks
:
{
[
type
:
number
]:
Tick
[]
}
=
{
[
LoaderEventType
.
BeginLoadingScript
]:
[],
[
LoaderEventType
.
BeginInvokeFactory
]:
[],
[
LoaderEventType
.
NodeBeginEvaluatingScript
]:
[],
[
LoaderEventType
.
NodeBeginNativeRequire
]:
[],
};
for
(
let
i
=
1
;
i
<
stats
.
length
-
1
;
i
++
)
{
const
stat
=
stats
[
i
];
const
nextStat
=
stats
[
i
+
1
];
if
(
nextStat
.
type
-
stat
.
type
>
2
)
{
//bad?!
break
;
}
i
+=
1
;
if
(
ticks
[
stat
.
type
])
{
ticks
[
stat
.
type
].
push
(
new
Tick
(
stat
,
nextStat
));
}
}
ticks
[
LoaderEventType
.
BeginInvokeFactory
].
sort
(
Tick
.
compareUsingStartTimestamp
);
ticks
[
LoaderEventType
.
BeginInvokeFactory
].
sort
(
Tick
.
compareUsingStartTimestamp
);
ticks
[
LoaderEventType
.
NodeBeginEvaluatingScript
].
sort
(
Tick
.
compareUsingStartTimestamp
);
ticks
[
LoaderEventType
.
NodeBeginNativeRequire
].
sort
(
Tick
.
compareUsingStartTimestamp
);
const
ret
=
{
'
Load Script
'
:
ticks
[
LoaderEventType
.
BeginLoadingScript
].
map
(
t
=>
t
.
toTableObject
()),
'
(Node) Load Script
'
:
ticks
[
LoaderEventType
.
NodeBeginNativeRequire
].
map
(
t
=>
t
.
toTableObject
()),
'
Eval Script
'
:
ticks
[
LoaderEventType
.
BeginInvokeFactory
].
map
(
t
=>
t
.
toTableObject
()),
'
(Node) Eval Script
'
:
ticks
[
LoaderEventType
.
NodeBeginEvaluatingScript
].
map
(
t
=>
t
.
toTableObject
()),
};
function
total
(
ticks
:
Tick
[]):
number
{
let
sum
=
0
;
for
(
const
tick
of
ticks
)
{
sum
+=
tick
.
duration
;
}
return
sum
;
}
// totals
ret
[
'
Load Script
'
].
push
({
[
'
Path
'
]:
'
TOTAL TIME
'
,
[
'
Took (ms)
'
]:
total
(
ticks
[
LoaderEventType
.
BeginLoadingScript
]).
toFixed
(
2
)
});
ret
[
'
Eval Script
'
].
push
({
[
'
Path
'
]:
'
TOTAL TIME
'
,
[
'
Took (ms)
'
]:
total
(
ticks
[
LoaderEventType
.
BeginInvokeFactory
]).
toFixed
(
2
)
});
ret
[
'
(Node) Load Script
'
].
push
({
[
'
Path
'
]:
'
TOTAL TIME
'
,
[
'
Took (ms)
'
]:
total
(
ticks
[
LoaderEventType
.
NodeBeginNativeRequire
]).
toFixed
(
2
)
});
ret
[
'
(Node) Eval Script
'
].
push
({
[
'
Path
'
]:
'
TOTAL TIME
'
,
[
'
Took (ms)
'
]:
total
(
ticks
[
LoaderEventType
.
NodeBeginEvaluatingScript
]).
toFixed
(
2
)
});
return
ret
;
}
}
...
...
@@ -345,7 +262,7 @@ export class ReportPerformanceIssueAction extends Action {
let
nodeModuleLoadTime
:
number
;
if
(
this
.
environmentService
.
performance
)
{
nodeModuleLoadTime
=
this
.
computeNodeModulesLoadTime
()
;
nodeModuleLoadTime
=
LoaderStat
.
getLoaderStats
().
nodeRequireTotal
;
}
...
...
@@ -374,22 +291,6 @@ ${ this.generatePerformanceTable(metrics, nodeModuleLoadTime)}
return
`
${
baseUrl
}
${
queryStringPrefix
}
body =
${
body
}
`
;
}
private
computeNodeModulesLoadTime
():
number
{
const
stats
=
<
ILoaderEvent
[]
>
(
<
any
>
require
).
getStats
();
let
total
=
0
;
for
(
let
i
=
0
,
len
=
stats
.
length
;
i
<
len
;
i
++
)
{
if
(
stats
[
i
].
type
===
LoaderEventType
.
NodeEndNativeRequire
)
{
if
(
stats
[
i
-
1
].
type
===
LoaderEventType
.
NodeBeginNativeRequire
&&
stats
[
i
-
1
].
detail
===
stats
[
i
].
detail
)
{
const
dur
=
(
stats
[
i
].
timestamp
-
stats
[
i
-
1
].
timestamp
);
total
+=
dur
;
}
}
}
return
Math
.
round
(
total
);
}
private
generatePerformanceTable
(
metrics
:
IStartupMetrics
,
nodeModuleLoadTime
?:
number
):
string
{
let
tableHeader
=
`| Component | Task | Duration(ms) | Info |
| ---| ---| ---| ---| `
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录