diff --git a/Cargo.lock b/Cargo.lock index cd176608ba..6b29f08031 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "annotate-snippets" version = "0.6.1" @@ -368,6 +374,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.73" @@ -416,6 +428,45 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" +[[package]] +name = "ciborium" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "bitflags", + "clap_lex 0.2.4", + "indexmap", + "textwrap 0.16.0", +] + [[package]] name = "clap" version = "4.0.15" @@ -425,7 +476,7 @@ dependencies = [ "atty", "bitflags", "clap_derive", - "clap_lex", + "clap_lex 0.3.0", "once_cell", "strsim", "termcolor", @@ -444,6 +495,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "clap_lex" version = "0.3.0" @@ -548,6 +608,42 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "criterion" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +dependencies = [ + "anes", + "atty", + "cast", + "ciborium", + "clap 3.2.23", + "criterion-plot", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + [[package]] name = "crossbeam-channel" version = "0.5.6" @@ -1041,6 +1137,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.12.3" @@ -1571,6 +1673,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.2.3" @@ -1779,6 +1887,34 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "plotters" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" + +[[package]] +name = "plotters-svg" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +dependencies = [ + "plotters-backend", +] + [[package]] name = "polling" version = "2.3.0" @@ -2061,11 +2197,12 @@ dependencies = [ "bincode", "cacache", "chrono", - "clap", + "clap 4.0.15", "clearscreen", "codegen", "colored", "common-path", + "criterion", "dirs 4.0.0", "fern", "filetime", @@ -2089,7 +2226,7 @@ dependencies = [ "strum", "strum_macros", "test-case", - "textwrap", + "textwrap 0.15.1", "titlecase", "toml", "update-informer", @@ -2549,6 +2686,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + [[package]] name = "thiserror" version = "1.0.37" @@ -2589,6 +2732,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 3146bbad63..03b7c6db74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ getrandom = { version = "0.2.7", features = ["js"] } [dev-dependencies] assert_cmd = { version = "2.0.4" } codegen = { version = "0.2.0" } +criterion = { version = "0.4.0" } insta = { version = "1.19.1", features = ["yaml"] } test-case = { version = "2.2.2" } @@ -69,3 +70,7 @@ opt-level = 3 [profile.dev.package.similar] opt-level = 3 + +[[bench]] +name = "source_code_locator" +harness = false diff --git a/benches/source_code_locator.rs b/benches/source_code_locator.rs new file mode 100644 index 0000000000..f5ce95f213 --- /dev/null +++ b/benches/source_code_locator.rs @@ -0,0 +1,16 @@ +use std::path::Path; + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +use ruff::ast::operations::{compute_offsets, compute_offsets_v0}; +use ruff::fs; + +fn criterion_benchmark(c: &mut Criterion) { + let contents = fs::read_file(Path::new("resources/test/fixtures/D.py")).unwrap(); + c.bench_function("compute_offsets", |b| { + b.iter(|| compute_offsets(black_box(&contents))) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/src/ast/operations.rs b/src/ast/operations.rs index a6d2af58f9..bf9bf9b044 100644 --- a/src/ast/operations.rs +++ b/src/ast/operations.rs @@ -125,6 +125,28 @@ pub struct SourceCodeLocator<'a> { offsets: OnceCell>>, } +pub fn compute_offsets(contents: &str) -> Vec> { + let mut offsets = vec![vec![]]; + let mut line_index = 0; + let mut char_index = 0; + let mut newline = false; + for (i, char) in contents.char_indices() { + offsets[line_index].push(i); + + newline = char == '\n'; + if newline { + line_index += 1; + offsets.push(vec![]); + char_index = i + char.len_utf8(); + } + } + // If we end in a newline, add an extra character to indicate the start of that line. + if newline { + offsets[line_index].push(char_index); + } + offsets +} + impl<'a> SourceCodeLocator<'a> { pub fn new(contents: &'a str) -> Self { SourceCodeLocator { @@ -133,31 +155,8 @@ impl<'a> SourceCodeLocator<'a> { } } - fn compute_offsets(content: &str) -> Vec> { - let mut offsets = vec![vec![]]; - let mut line_index = 0; - let mut char_index = 0; - let mut newline = false; - for (i, char) in content.char_indices() { - offsets[line_index].push(i); - char_index = i + char.len_utf8(); - - newline = char == '\n'; - if newline { - line_index += 1; - offsets.push(vec![]); - } - } - // If we end in a newline, add an extra character to indicate the start of that line. - if newline { - offsets[line_index].push(char_index); - } - offsets - } - fn get_or_init_offsets(&self) -> &Vec> { - self.offsets - .get_or_init(|| Self::compute_offsets(self.contents)) + self.offsets.get_or_init(|| compute_offsets(self.contents)) } pub fn slice_source_code_at(&self, location: &Location) -> &'a str { diff --git a/src/lib.rs b/src/lib.rs index f893ef564b..0faf98ba5e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ use crate::linter::{check_path, tokenize}; use crate::message::Message; use crate::settings::configuration::Configuration; -mod ast; +pub mod ast; mod autofix; pub mod cache; pub mod check_ast;