mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-06 08:51:14 -03:00
Improve codegen of line_offset_of_character_at_offset
This function is a hotspot, but it has inefficient codegen: 1. For whatever reason, the chars() iterator of wstr is slower than that of a slice. Use the slice. 2. Unnecessary overflow checks were preventing vectorization. Switch to a more optimized implementation. This improves aliases benchmark time by about 9%.
This commit is contained in:
@@ -8,6 +8,20 @@
|
||||
use crate::wchar::{decode_byte_from_char, prelude::*};
|
||||
use crate::wutil::encoding::{wcrtomb, zero_mbstate, AT_LEAST_MB_LEN_MAX};
|
||||
|
||||
/// Return the number of newlines in a string.
|
||||
pub fn count_newlines(s: &wstr) -> usize {
|
||||
// This is a performance-sensitive function.
|
||||
// The native filter().count() produces sub-optimal codegen because of overflow checks,
|
||||
// which we currently enable in release mode. Implement it more efficiently.
|
||||
let mut count: usize = 0;
|
||||
for c in s.as_char_slice() {
|
||||
if *c == '\n' {
|
||||
count = count.wrapping_add(1);
|
||||
}
|
||||
}
|
||||
count
|
||||
}
|
||||
|
||||
/// Test if a string prefixes another without regard to case. Returns true if a is a prefix of b.
|
||||
pub fn string_prefixes_string_case_insensitive(proposed_prefix: &wstr, value: &wstr) -> bool {
|
||||
let prefix_size = proposed_prefix.len();
|
||||
@@ -643,3 +657,13 @@ fn test_line_iterator() {
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_newlines() {
|
||||
assert_eq!(count_newlines(L!("")), 0);
|
||||
assert_eq!(count_newlines(L!("foo")), 0);
|
||||
assert_eq!(count_newlines(L!("foo\nbar")), 1);
|
||||
assert_eq!(count_newlines(L!("foo\nbar\nbaz")), 2);
|
||||
assert_eq!(count_newlines(L!("\n")), 1);
|
||||
assert_eq!(count_newlines(L!("\n\n")), 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user