Auto merge of #17843 - mo8it:flycheck, r=Veykril

internal: Performance optimizations

- Use `Command::arg` directly
- Avoid the overhead of the `select!` macro when possible
- Use `select_biased!`
This commit is contained in:
bors 2024-08-12 09:27:47 +00:00
commit e75bd2e00f
2 changed files with 39 additions and 37 deletions

View file

@ -3,7 +3,7 @@
use std::{fmt, io, process::Command, time::Duration}; use std::{fmt, io, process::Command, time::Duration};
use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; use crossbeam_channel::{select_biased, unbounded, Receiver, Sender};
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use serde::Deserialize; use serde::Deserialize;
@ -260,13 +260,14 @@ impl FlycheckActor {
} }
fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> { fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
if let Ok(msg) = inbox.try_recv() { let Some(command_receiver) = &self.command_receiver else {
// give restarts a preference so check outputs don't block a restart or stop return inbox.recv().ok().map(Event::RequestStateChange);
return Some(Event::RequestStateChange(msg)); };
}
select! { // Biased to give restarts a preference so check outputs don't block a restart or stop
select_biased! {
recv(inbox) -> msg => msg.ok().map(Event::RequestStateChange), recv(inbox) -> msg => msg.ok().map(Event::RequestStateChange),
recv(self.command_receiver.as_ref().unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())), recv(command_receiver) -> msg => Some(Event::CheckEvent(msg.ok())),
} }
} }
@ -388,7 +389,7 @@ impl FlycheckActor {
package: Option<&str>, package: Option<&str>,
saved_file: Option<&AbsPath>, saved_file: Option<&AbsPath>,
) -> Option<Command> { ) -> Option<Command> {
let (mut cmd, args) = match &self.config { match &self.config {
FlycheckConfig::CargoCommand { command, options, ansi_color_output } => { FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
let mut cmd = Command::new(Tool::Cargo.path()); let mut cmd = Command::new(Tool::Cargo.path());
if let Some(sysroot_root) = &self.sysroot_root { if let Some(sysroot_root) = &self.sysroot_root {
@ -419,7 +420,8 @@ impl FlycheckActor {
cmd.arg("--keep-going"); cmd.arg("--keep-going");
options.apply_on_command(&mut cmd); options.apply_on_command(&mut cmd);
(cmd, options.extra_args.clone()) cmd.args(&options.extra_args);
Some(cmd)
} }
FlycheckConfig::CustomCommand { FlycheckConfig::CustomCommand {
command, command,
@ -448,35 +450,32 @@ impl FlycheckActor {
} }
} }
if args.contains(&SAVED_FILE_PLACEHOLDER.to_owned()) {
// If the custom command has a $saved_file placeholder, and // If the custom command has a $saved_file placeholder, and
// we're saving a file, replace the placeholder in the arguments. // we're saving a file, replace the placeholder in the arguments.
if let Some(saved_file) = saved_file { if let Some(saved_file) = saved_file {
let args = args for arg in args {
.iter()
.map(|arg| {
if arg == SAVED_FILE_PLACEHOLDER { if arg == SAVED_FILE_PLACEHOLDER {
saved_file.to_string() cmd.arg(saved_file);
} else { } else {
arg.clone() cmd.arg(arg);
}
} }
})
.collect();
(cmd, args)
} else { } else {
for arg in args {
if arg == SAVED_FILE_PLACEHOLDER {
// The custom command has a $saved_file placeholder, // The custom command has a $saved_file placeholder,
// but we had an IDE event that wasn't a file save. Do nothing. // but we had an IDE event that wasn't a file save. Do nothing.
return None; return None;
} }
} else {
(cmd, args.clone())
}
}
};
cmd.args(args); cmd.arg(arg);
}
}
Some(cmd) Some(cmd)
} }
}
}
#[track_caller] #[track_caller]
fn send(&self, check_task: FlycheckMessage) { fn send(&self, check_task: FlycheckMessage) {

View file

@ -13,7 +13,7 @@ use std::{
sync::atomic::AtomicUsize, sync::atomic::AtomicUsize,
}; };
use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; use crossbeam_channel::{select, unbounded, Receiver, Sender};
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
use rayon::iter::{IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator}; use rayon::iter::{IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator};
@ -85,10 +85,13 @@ impl NotifyActor {
} }
fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> { fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
let watcher_receiver = self.watcher.as_ref().map(|(_, receiver)| receiver); let Some((_, watcher_receiver)) = &self.watcher else {
return receiver.recv().ok().map(Event::Message);
};
select! { select! {
recv(receiver) -> it => it.ok().map(Event::Message), recv(receiver) -> it => it.ok().map(Event::Message),
recv(watcher_receiver.unwrap_or(&never())) -> it => Some(Event::NotifyEvent(it.unwrap())), recv(watcher_receiver) -> it => Some(Event::NotifyEvent(it.unwrap())),
} }
} }