From 3c69076e0afbe05316cf4b91c7e1f82ad1a97ac7 Mon Sep 17 00:00:00 2001 From: Avril Date: Sun, 13 Sep 2020 10:22:15 +0100 Subject: [PATCH] improved efficiency a bit --- Cargo.toml | 6 +- src/loli/encoding.rs | 14 ++-- src/main.rs | 6 +- src/search.rs | 143 +++++++++++++++++++++++++++++++++++++ src/work_async/progress.rs | 8 ++- 5 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 src/search.rs diff --git a/Cargo.toml b/Cargo.toml index 9f86694..2c3d537 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lolistealer" -version = "1.3.1" +version = "1.3.2" authors = ["Avril "] edition = "2018" license = "GPL-3.0-or-later" @@ -15,7 +15,10 @@ homepage = "https://flanchan.moe" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +default = ["async", "mem_find"] + async = ["tokio"] +mem_find = ["memchr"] [profile.release] opt-level = 3 @@ -30,6 +33,7 @@ reqwest = {version = "0.10", features= ["stream"]} memmap = "0.7" getrandom = "0.1" base64 = "0.12" +memchr = {version = "2.3", optional = true} [build-dependencies] rustc_version = "0.2" diff --git a/src/loli/encoding.rs b/src/loli/encoding.rs index 7a2320c..052d2a0 100644 --- a/src/loli/encoding.rs +++ b/src/loli/encoding.rs @@ -80,15 +80,11 @@ pub const fn data_size(base64: usize) -> usize ((4 * base64 / 3) + 3) & !3 } -#[inline] -fn find(haystack: &[u8], needle: &[u8]) -> Option { - haystack.windows(needle.len()).position(|window| window == needle) -} - -#[inline] -fn find_back(haystack: &[u8], needle: &[u8]) -> Option { - haystack.windows(needle.len()).rev().position(|window| window == needle).and_then(|v| Some(haystack.len() - v)) -} +use crate::{ + search::{ + find, find_back, + }, +}; const MARKER_BASE64_BEGIN: &[u8] = b"base64,"; const MARKER_BASE64_END: &[u8] = b"' /> Option +{ + if needle.len() < 1 { + return None; + } + for sz in memchr_iter(needle[0], haystack) { + if &haystack[sz..std::cmp::min(sz+needle.len(), haystack.len())] == needle { + return Some(sz); + } + } + + None +} + +#[inline] +#[cfg(feature="mem_find")] +pub fn find_back(haystack: &[u8], needle: &[u8]) -> Option +{ + if needle.len() < 1 { + return None; + } + for sz in memrchr_iter(needle[0], haystack) { + if &haystack[sz..std::cmp::min(sz+needle.len(), haystack.len())] == needle { + return Some(sz+needle.len()); + } + } + + None +} + +#[inline(always)] +#[cfg(not(feature="mem_find"))] +pub fn find(haystack: &[u8], needle: &[u8]) -> Option +{ + wfind(haystack, needle) +} + + +#[inline(always)] +#[cfg(not(feature="mem_find"))] +pub fn find_back(haystack: &[u8], needle: &[u8]) -> Option +{ + wfind_back(haystack, needle) +} + +#[inline] +fn wfind(haystack: &[u8], needle: &[u8]) -> Option { + haystack.windows(needle.len()).position(|window| window == needle) +} + +#[inline] +fn wfind_back(haystack: &[u8], needle: &[u8]) -> Option { + haystack.windows(needle.len()).rev().position(|window| window == needle).and_then(|v| Some(haystack.len() - v)) +} + +#[cfg(test)] +mod tests +{ + use super::*; + const HAYSTACK: &str = r#"awn r9anw09e8tja\ł]erj\æ][jw3-9r8ja9w8jera9je\đ →je\¶}j g\}iejđ \→æje\¶iaj-wie ¶3-928H09Q82H39 -Ł ¶j@\}]ẻ¶\ }æ]ĸ«ø𳶲38r 9W³¶\ ³¶}→ E→ ÞÆØ→ŁẺLOLE!!!¶ØĸÆŁŁ¶ĸØÞ@ĸ³øþĸ}@→Ħ³¶Ø@ŁŁĸ}→²ĦE}Ħ¶ 30r EJ}AJ"#; + const NEEDLE: &str = "LOLE!!!"; + #[test] + fn mfind() + { + let haystack = HAYSTACK.as_bytes(); + let needle= NEEDLE.as_bytes(); + + assert_eq!(wfind(haystack, needle), find(haystack, needle)); + } + + #[test] + fn mfind_back() + { + let haystack = HAYSTACK.as_bytes(); + let needle= NEEDLE.as_bytes(); + + assert_eq!(wfind_back(haystack, needle), find_back(haystack, needle)); + } + + #[cfg(nightly)] + mod benchmarks { + use super::{ + NEEDLE, HAYSTACK, + }; + use test::{ + Bencher, black_box, + }; + #[bench] + fn mfind(b: &mut Bencher) + { + + let haystack = HAYSTACK.as_bytes(); + let needle= NEEDLE.as_bytes(); + + b.iter(|| { + black_box(super::find(haystack,needle)); + }); + } + #[bench] + fn mfind_back(b: &mut Bencher) + { + + let haystack = HAYSTACK.as_bytes(); + let needle= NEEDLE.as_bytes(); + + b.iter(|| { + black_box(super::find_back(haystack,needle)); + }); + } + + #[bench] + fn wfind(b: &mut Bencher) + { + + let haystack = HAYSTACK.as_bytes(); + let needle= NEEDLE.as_bytes(); + + b.iter(|| { + black_box(super::wfind(haystack,needle)); + }); + } + #[bench] + fn wfind_back(b: &mut Bencher) + { + + let haystack = HAYSTACK.as_bytes(); + let needle= NEEDLE.as_bytes(); + + b.iter(|| { + black_box(super::wfind_back(haystack,needle)); + }); + } + } +} diff --git a/src/work_async/progress.rs b/src/work_async/progress.rs index f0cf6e5..30711aa 100644 --- a/src/work_async/progress.rs +++ b/src/work_async/progress.rs @@ -22,6 +22,7 @@ use termprogress::{ enum CommandInternal { + None, PrintLine(String), BumpMax(u64), Bump(u64), @@ -279,8 +280,8 @@ impl AsyncProgressCounter (small as f64) / (large as f64) } - while let Some(com) = self.reader.recv().await { - match &com.internal { + while let Some(mut com) = self.reader.recv().await { + match std::mem::replace(&mut com.internal, CommandInternal::None) { CommandInternal::PrintLine(line) => bar.println(&line[..]), CommandInternal::BumpMax(by) => { large += by; @@ -316,8 +317,9 @@ impl AsyncProgressCounter CommandInternal::ClearTask(Some(title)) => { task.clear(); bar.set_title(&title[..]); - self.title = title.clone(); + self.title = title; }, + _ => {}, } } })