Skip to content

Commit 85526a2

Browse files
committed
Check the pattern before anything else, since it doesn't require metadata
This should partially address #432 by decreasing the number of stat() calls: $ strace -c -f ./fd-before '.h$' -j1 /usr -S +1k >/dev/null % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 100.00 3.700169 3 983938 38022 stat $ strace -c -f ./fd-after '.h$' -j1 /usr -S +1k >/dev/null % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 100.00 0.671723 4 162052 38021 stat Though it's not as good as possible: $ strace -c -f find /usr -name '*.h' -size +1k >/dev/null % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 18.75 0.449866 3 136199 newfstatat $ strace -c -f bfs /usr -name '*.h' -size +1k >/dev/null % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 15.01 0.216024 3 60211 1 statx Performance is much better when metadata is required: $ hyperfine ./fd-{before,after}" '.h$' -j1 /usr -S +1k" Benchmark #1: ./fd-before '.h$' -j1 /usr -S +1k Time (mean ± σ): 2.707 s ± 0.042 s [User: 890.8 ms, System: 1939.7 ms] Range (min … max): 2.659 s … 2.786 s 10 runs Benchmark #2: ./fd-after '.h$' -j1 /usr -S +1k Time (mean ± σ): 1.562 s ± 0.034 s [User: 726.2 ms, System: 957.9 ms] Range (min … max): 1.536 s … 1.648 s 10 runs Summary './fd-after '.h$' -j1 /usr -S +1k' ran 1.73 ± 0.05 times faster than './fd-before '.h$' -j1 /usr -S +1k' While remaining the same when it's not: tavianator@graviton $ hyperfine ./fd-{before,after}" '.h$' -j1 /usr" Benchmark #1: ./fd-before '.h$' -j1 /usr Time (mean ± σ): 1.341 s ± 0.016 s [User: 664.3 ms, System: 761.2 ms] Range (min … max): 1.309 s … 1.361 s 10 runs Benchmark #2: ./fd-after '.h$' -j1 /usr Time (mean ± σ): 1.338 s ± 0.012 s [User: 684.1 ms, System: 741.1 ms] Range (min … max): 1.310 s … 1.350 s 10 runs Summary './fd-after '.h$' -j1 /usr' ran 1.00 ± 0.02 times faster than './fd-before '.h$' -j1 /usr'
1 parent 35945c4 commit 85526a2

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

src/walk.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,27 @@ fn spawn_senders(
267267
return ignore::WalkState::Continue;
268268
}
269269

270+
// Check the name first, since it doesn't require metadata
271+
272+
let entry_path = entry.path();
273+
274+
let search_str_o = if config.search_full_path {
275+
match fshelper::path_absolute_form(entry_path) {
276+
Ok(path_abs_buf) => Some(path_abs_buf.to_string_lossy().into_owned().into()),
277+
Err(_) => {
278+
print_error_and_exit!("Unable to retrieve absolute path.");
279+
}
280+
}
281+
} else {
282+
entry_path.file_name().map(|f| f.to_string_lossy())
283+
};
284+
285+
if let Some(search_str) = search_str_o {
286+
if !pattern.is_match(&*search_str) {
287+
return ignore::WalkState::Continue;
288+
}
289+
}
290+
270291
// Filter out unwanted file types.
271292

272293
if let Some(ref file_types) = config.file_types {
@@ -294,8 +315,6 @@ fn spawn_senders(
294315
}
295316
}
296317

297-
let entry_path = entry.path();
298-
299318
// Filter out unwanted extensions.
300319
if let Some(ref exts_regex) = config.extensions {
301320
if let Some(path_str) = entry_path.file_name().and_then(|s| s.to_str()) {
@@ -345,25 +364,10 @@ fn spawn_senders(
345364
}
346365
}
347366

348-
let search_str_o = if config.search_full_path {
349-
match fshelper::path_absolute_form(entry_path) {
350-
Ok(path_abs_buf) => Some(path_abs_buf.to_string_lossy().into_owned().into()),
351-
Err(_) => {
352-
print_error_and_exit!("Unable to retrieve absolute path.");
353-
}
354-
}
355-
} else {
356-
entry_path.file_name().map(|f| f.to_string_lossy())
357-
};
358-
359-
if let Some(search_str) = search_str_o {
360-
if pattern.is_match(&*search_str) {
361-
// TODO: take care of the unwrap call
362-
tx_thread
363-
.send(WorkerResult::Entry(entry_path.to_owned()))
364-
.unwrap()
365-
}
366-
}
367+
// TODO: take care of the unwrap call
368+
tx_thread
369+
.send(WorkerResult::Entry(entry_path.to_owned()))
370+
.unwrap();
367371

368372
ignore::WalkState::Continue
369373
})

0 commit comments

Comments
 (0)