mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
perf(lsp): instrument all ops with performance marks (#21536)
Adds performance measurements for all ops used by the LSP. Also changes output of "Language server status" page to include more precise information. Current suspicion is that computing "script version" takes a long time for some users.
This commit is contained in:
parent
98121de5be
commit
88566cee72
4 changed files with 46 additions and 17 deletions
|
@ -3809,15 +3809,11 @@ impl Inner {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
contents
|
contents
|
||||||
.push_str("\n## Performance\n\n|Name|Duration|Count|\n|---|---|---|\n");
|
.push_str("\n## Performance\n\n|Name|Duration|Count|\n|---|---|---|\n");
|
||||||
let mut averages = self.performance.averages();
|
let mut averages = self.performance.averages_as_f64();
|
||||||
averages.sort();
|
averages.sort_by(|a, b| a.0.cmp(&b.0));
|
||||||
for average in averages {
|
for (name, count, average_duration) in averages {
|
||||||
writeln!(
|
writeln!(contents, "|{}|{}ms|{}|", name, average_duration, count)
|
||||||
contents,
|
.unwrap();
|
||||||
"|{}|{}ms|{}|",
|
|
||||||
average.name, average.average_duration, average.count
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
Some(contents)
|
Some(contents)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -51,7 +51,12 @@ pub struct PerformanceMeasure {
|
||||||
|
|
||||||
impl fmt::Display for PerformanceMeasure {
|
impl fmt::Display for PerformanceMeasure {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{} ({}ms)", self.name, self.duration.as_millis())
|
write!(
|
||||||
|
f,
|
||||||
|
"{} ({}ms)",
|
||||||
|
self.name,
|
||||||
|
self.duration.as_micros() as f64 / 1000.0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +137,24 @@ impl Performance {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn averages_as_f64(&self) -> Vec<(String, u32, f64)> {
|
||||||
|
let mut averages: HashMap<String, Vec<Duration>> = HashMap::new();
|
||||||
|
for measure in self.measures.lock().iter() {
|
||||||
|
averages
|
||||||
|
.entry(measure.name.clone())
|
||||||
|
.or_default()
|
||||||
|
.push(measure.duration);
|
||||||
|
}
|
||||||
|
averages
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, d)| {
|
||||||
|
let count = d.len() as u32;
|
||||||
|
let a = d.into_iter().sum::<Duration>() / count;
|
||||||
|
(k, count, a.as_micros() as f64 / 1000.0)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn mark_inner<S: AsRef<str>, V: Serialize>(
|
fn mark_inner<S: AsRef<str>, V: Serialize>(
|
||||||
&self,
|
&self,
|
||||||
name: S,
|
name: S,
|
||||||
|
|
|
@ -3842,7 +3842,8 @@ fn op_is_cancelled(state: &mut OpState) -> bool {
|
||||||
#[op2(fast)]
|
#[op2(fast)]
|
||||||
fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
|
fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
|
||||||
let state = state.borrow::<State>();
|
let state = state.borrow::<State>();
|
||||||
match ModuleSpecifier::parse(&path) {
|
let mark = state.performance.mark("tsc.op.op_is_node_file");
|
||||||
|
let r = match ModuleSpecifier::parse(&path) {
|
||||||
Ok(specifier) => state
|
Ok(specifier) => state
|
||||||
.state_snapshot
|
.state_snapshot
|
||||||
.npm
|
.npm
|
||||||
|
@ -3850,7 +3851,9 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
|
||||||
.map(|n| n.npm_resolver.in_npm_package(&specifier))
|
.map(|n| n.npm_resolver.in_npm_package(&specifier))
|
||||||
.unwrap_or(false),
|
.unwrap_or(false),
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
};
|
||||||
|
state.performance.measure(mark);
|
||||||
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
@ -3946,6 +3949,7 @@ fn op_respond(state: &mut OpState, #[serde] args: Response) {
|
||||||
#[serde]
|
#[serde]
|
||||||
fn op_script_names(state: &mut OpState) -> Vec<String> {
|
fn op_script_names(state: &mut OpState) -> Vec<String> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
|
let mark = state.performance.mark("tsc.op.op_script_names");
|
||||||
let documents = &state.state_snapshot.documents;
|
let documents = &state.state_snapshot.documents;
|
||||||
let all_docs = documents.documents(DocumentsFilter::AllDiagnosable);
|
let all_docs = documents.documents(DocumentsFilter::AllDiagnosable);
|
||||||
let mut seen = HashSet::new();
|
let mut seen = HashSet::new();
|
||||||
|
@ -3985,13 +3989,15 @@ fn op_script_names(state: &mut OpState) -> Vec<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
let r = result
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|s| match ModuleSpecifier::parse(&s) {
|
.map(|s| match ModuleSpecifier::parse(&s) {
|
||||||
Ok(s) => state.specifier_map.denormalize(&s),
|
Ok(s) => state.specifier_map.denormalize(&s),
|
||||||
Err(_) => s,
|
Err(_) => s,
|
||||||
})
|
})
|
||||||
.collect()
|
.collect();
|
||||||
|
state.performance.measure(mark);
|
||||||
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2]
|
#[op2]
|
||||||
|
@ -4001,10 +4007,11 @@ fn op_script_version(
|
||||||
#[string] specifier: &str,
|
#[string] specifier: &str,
|
||||||
) -> Result<Option<String>, AnyError> {
|
) -> Result<Option<String>, AnyError> {
|
||||||
let state = state.borrow_mut::<State>();
|
let state = state.borrow_mut::<State>();
|
||||||
// this op is very "noisy" and measuring its performance is not useful, so we
|
let mark = state.performance.mark("tsc.op.op_script_version");
|
||||||
// don't measure it uniquely anymore.
|
|
||||||
let specifier = state.specifier_map.normalize(specifier)?;
|
let specifier = state.specifier_map.normalize(specifier)?;
|
||||||
Ok(state.script_version(&specifier))
|
let r = state.script_version(&specifier);
|
||||||
|
state.performance.measure(mark);
|
||||||
|
Ok(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create and setup a JsRuntime based on a snapshot. It is expected that the
|
/// Create and setup a JsRuntime based on a snapshot. It is expected that the
|
||||||
|
|
|
@ -8318,7 +8318,10 @@ fn lsp_performance() {
|
||||||
"tsc.host.$getDiagnostics",
|
"tsc.host.$getDiagnostics",
|
||||||
"tsc.host.$getSupportedCodeFixes",
|
"tsc.host.$getSupportedCodeFixes",
|
||||||
"tsc.host.getQuickInfoAtPosition",
|
"tsc.host.getQuickInfoAtPosition",
|
||||||
|
"tsc.op.op_is_node_file",
|
||||||
"tsc.op.op_load",
|
"tsc.op.op_load",
|
||||||
|
"tsc.op.op_script_names",
|
||||||
|
"tsc.op.op_script_version",
|
||||||
"tsc.request.$configure",
|
"tsc.request.$configure",
|
||||||
"tsc.request.$getAssets",
|
"tsc.request.$getAssets",
|
||||||
"tsc.request.$getSupportedCodeFixes",
|
"tsc.request.$getSupportedCodeFixes",
|
||||||
|
|
Loading…
Add table
Reference in a new issue