mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-07-26 17:51:56 -07:00
Compare commits
80 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
263e2b012f | ||
|
b80a986721 | ||
|
8a91d3132f | ||
|
525d051172 | ||
|
5a9883d27c | ||
|
f462d092e7 | ||
|
fe84928c85 | ||
|
f7eaf67fc3 | ||
|
c1c92e4fee | ||
|
5644bbe43a | ||
|
aeb3a5ba0f | ||
|
24e14a0341 | ||
|
2a2b1506d4 | ||
|
4d6b3c727e | ||
|
c2bf9e3d45 | ||
|
dad73b92eb | ||
|
b0d8ff6f4a | ||
|
0263a401f6 | ||
|
4cb1b9ccc0 | ||
|
6f80e2e126 | ||
|
f9bff90842 | ||
|
5af4ec0056 | ||
|
9e2f10b893 | ||
|
69095cf5c3 | ||
|
7402db7b43 | ||
|
7698b60256 | ||
|
e7fb0fd267 | ||
|
29b59074c7 | ||
|
ee5eb2d659 | ||
|
bf8094344a | ||
|
a0819978aa | ||
|
5b7c17e2fb | ||
|
bf56b3bb8e | ||
|
9299d84d41 | ||
|
2cf1a08969 | ||
|
665b6016e3 | ||
|
33231622f3 | ||
|
919c5c7299 | ||
|
f9bf1e4a22 | ||
|
f7ee914dd3 | ||
|
0a63158a61 | ||
|
6cb604f38f | ||
|
bfbbfbf979 | ||
|
403ba5fdc8 | ||
|
8f87a4e8ac | ||
|
d27d3e675f | ||
|
bf5d873099 | ||
|
bc9d12c4c8 | ||
|
5a0c873f61 | ||
|
65fec147d6 | ||
|
7fbf2f014c | ||
|
d22a3ca3e5 | ||
|
e9ec52b7f9 | ||
|
0d14c74e63 | ||
|
1c5884b2f9 | ||
|
8203a80ac7 | ||
|
0e46171e3b | ||
|
f5c85827ce | ||
|
7cefc55238 | ||
|
92c918ebd9 | ||
|
c24f8fd50f | ||
|
73272cf8a6 | ||
|
4212a8b9cb | ||
|
983c7fd6f9 | ||
|
7cd02e9b7e | ||
|
5fdfae2f15 | ||
|
7057ee91de | ||
|
fdca74148d | ||
|
f11d9fb922 | ||
|
1115c23a4c | ||
|
8c5eaa40b2 | ||
|
3c05954c86 | ||
|
cf3a33cea7 | ||
|
8aa2ba3eb1 | ||
|
466cd70a8e | ||
|
954fbeb1d8 | ||
|
68fa50709e | ||
|
ab91e4b874 | ||
|
2b943eda47 | ||
|
37544c092f |
12
.gitignore
vendored
12
.gitignore
vendored
@@ -1,14 +1,4 @@
|
||||
.*.swp
|
||||
tags
|
||||
target
|
||||
*.lock
|
||||
tmp
|
||||
*.csv
|
||||
*.fst
|
||||
*-got
|
||||
*.csv.idx
|
||||
words
|
||||
98m*
|
||||
dict
|
||||
test
|
||||
months
|
||||
/grep/Cargo.lock
|
||||
|
@@ -15,9 +15,6 @@ matrix:
|
||||
- os: linux
|
||||
rust: nightly
|
||||
env: TARGET=x86_64-unknown-linux-musl
|
||||
- os: linux
|
||||
rust: nightly
|
||||
env: TARGET=x86_64-unknown-linux-gnu
|
||||
- os: osx
|
||||
rust: nightly
|
||||
env: TARGET=i686-apple-darwin
|
||||
|
261
Cargo.lock
generated
Normal file
261
Cargo.lock
generated
Normal file
@@ -0,0 +1,261 @@
|
||||
[root]
|
||||
name = "ripgrep"
|
||||
version = "0.1.13"
|
||||
dependencies = [
|
||||
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 0.6.83 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"grep 0.1.2",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deque"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "0.6.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fs2"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "grep"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memmap"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "simd"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
||||
"checksum docopt 0.6.83 (registry+https://github.com/rust-lang/crates.io-index)" = "fc42c6077823a361410c37d47c2535b73a190cbe10838dc4f400fe87c10c8c3b"
|
||||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
|
||||
"checksum fs2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd414e5a1a979b931bb92f41b7a54106d3f6d2e6c253e9ce943b7cd468251ef"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||
"checksum libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "408014cace30ee0f767b1c4517980646a573ec61a57957aeeabcac8ac0a02e8d"
|
||||
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
|
||||
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
|
||||
"checksum memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f20f72ed93291a72e22e8b16bb18762183bb4943f0f483da5b8be1a9e8192752"
|
||||
"checksum num_cpus 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8890e6084723d57d0df8d2720b0d60c6ee67d6c93e7169630e4371e88765dcad"
|
||||
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||
"checksum regex 0.1.77 (registry+https://github.com/rust-lang/crates.io-index)" = "64b03446c466d35b42f2a8b203c8e03ed8b91c0f17b56e1f84f7210a257aa665"
|
||||
"checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd"
|
||||
"checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
|
||||
"checksum simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5847c2d766ca7ce7227672850955802fabd779ba616aeabead4c2c3877023"
|
||||
"checksum strsim 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50c069df92e4b01425a8bf3576d5d417943a6a7272fbabaf5bd80b1aaa76442e"
|
||||
"checksum term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3deff8a2b3b6607d6d7cc32ac25c0b33709453ca9cceac006caac51e963cf94a"
|
||||
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
|
||||
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||
"checksum walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c66c0b9792f0a765345452775f3adbd28dde9d33f30d13e5dcc5ae17cf6f3780"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
15
Cargo.toml
15
Cargo.toml
@@ -1,10 +1,10 @@
|
||||
[package]
|
||||
publish = false
|
||||
name = "ripgrep"
|
||||
version = "0.1.0" #:version
|
||||
version = "0.1.13" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Line oriented search tool using Rust's regex library.
|
||||
Line oriented search tool using Rust's regex library. Combines the raw
|
||||
performance of grep with the usability of the silver searcher.
|
||||
"""
|
||||
documentation = "https://github.com/BurntSushi/ripgrep"
|
||||
homepage = "https://github.com/BurntSushi/ripgrep"
|
||||
@@ -23,21 +23,20 @@ name = "integration"
|
||||
path = "tests/tests.rs"
|
||||
|
||||
[dependencies]
|
||||
crossbeam = "0.2"
|
||||
deque = "0.3"
|
||||
docopt = "0.6"
|
||||
env_logger = "0.3"
|
||||
grep = { version = "0.1", path = "grep" }
|
||||
fnv = "1.0"
|
||||
grep = { version = "0.1.2", path = "grep" }
|
||||
lazy_static = "0.2"
|
||||
libc = "0.2"
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
memmap = "0.2"
|
||||
num_cpus = "1"
|
||||
regex = "0.1.75"
|
||||
regex-syntax = "0.3.5"
|
||||
regex = "0.1.77"
|
||||
rustc-serialize = "0.3"
|
||||
term = "0.4"
|
||||
thread_local = "0.2"
|
||||
walkdir = "0.1"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
|
14
Makefile
14
Makefile
@@ -1,14 +0,0 @@
|
||||
all:
|
||||
echo Nothing to do...
|
||||
|
||||
ctags:
|
||||
ctags --options=ctags.rust --languages=Rust src/*.rs src/*/*.rs
|
||||
|
||||
docs:
|
||||
cargo doc
|
||||
in-dir ./target/doc fix-perms
|
||||
rscp ./target/doc/* gopher:~/www/burntsushi.net/rustdoc/
|
||||
|
||||
push:
|
||||
git push origin master
|
||||
git push github master
|
258
README-NEW.md
Normal file
258
README-NEW.md
Normal file
@@ -0,0 +1,258 @@
|
||||
ripgrep (rg)
|
||||
------------
|
||||
`ripgrep` is a command line search tool that combines the usability of The
|
||||
Silver Searcher (an `ack` clone) with the raw speed of GNU grep. `ripgrep` has
|
||||
first class support on Windows, Mac and Linux, with binary downloads available
|
||||
for [every release](https://github.com/BurntSushi/ripgrep/releases).
|
||||
|
||||
[](https://travis-ci.org/BurntSushi/ripgrep)
|
||||
[](https://ci.appveyor.com/project/BurntSushi/ripgrep)
|
||||
[](https://crates.io/crates/ripgrep)
|
||||
|
||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
||||
|
||||
### Screenshot of search results
|
||||
|
||||
[](http://burntsushi.net/stuff/ripgrep1.png)
|
||||
|
||||
### Quick example comparing tools
|
||||
|
||||
This example searches the entire Linux kernel source tree (after running
|
||||
`make defconfig && make -j8`) for `[A-Z]+_SUSPEND`, where all matches must be
|
||||
words. Timings were collected on a system with an Intel i7-6900K 3.2 GHz.
|
||||
|
||||
Please remember that a single benchmark is never enough! See my
|
||||
[blog post on `ripgrep`](http://blog.burntsushi.net/ripgrep/)
|
||||
for a very detailed comparison with more benchmarks and analysis.
|
||||
|
||||
| Tool | Command | Line count | Time |
|
||||
| ---- | ------- | ---------- | ---- |
|
||||
| ripgrep | `rg -n -w '[A-Z]+_SUSPEND'` | 450 | **0.245s** |
|
||||
| [The Silver Searcher](https://github.com/ggreer/the_silver_searcher) | `ag -w '[A-Z]+_SUSPEND'` | 450 | 0.753s |
|
||||
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=C git grep -E -n -w '[A-Z]+_SUSPEND'` | 450 | 0.823s |
|
||||
| [git grep](https://www.kernel.org/pub/software/scm/git/docs/git-grep.html) | `LC_ALL=en_US.UTF-8 git grep -E -n -w '[A-Z]+_SUSPEND'` | 450 | 2.880s |
|
||||
| [sift](https://github.com/svent/sift) | `sift --git -n -w '[A-Z]+_SUSPEND'` | 450 | 3.656s |
|
||||
| [The Platinum Searcher](https://github.com/monochromegane/the_platinum_searcher) | `pt -w -e '[A-Z]+_SUSPEND'` | 450 | 12.369s |
|
||||
| [ack](http://beyondgrep.com/) | `ack -w '[A-Z]+_SUSPEND'` | 1878 | 16.952s |
|
||||
|
||||
(Yes, `ack` [has](https://github.com/petdance/ack2/issues/445) a
|
||||
[bug](https://github.com/petdance/ack2/issues/14).)
|
||||
|
||||
### Why should I use `ripgrep`?
|
||||
|
||||
* It can replace both The Silver Searcher and GNU grep because it is faster
|
||||
than both. (N.B. It is not, strictly speaking, a "drop-in" replacement for
|
||||
both, but the feature sets are far more similar than different.)
|
||||
* Like The Silver Searcher, `ripgrep` defaults to recursive directory search
|
||||
and won't search files ignored by your `.gitignore` files. It also ignores
|
||||
hidden and binary files by default. `ripgrep` also implements full support
|
||||
for `.gitignore`, where as there are many bugs related to that functionality
|
||||
in The Silver Searcher.
|
||||
* `ripgrep` can search specific types of files. For example, `rg -tpy foo`
|
||||
limits your search to Python files and `rg -Tjs foo` excludes Javascript
|
||||
files from your search. `ripgrep` can be taught about new file types with
|
||||
custom matching rules.
|
||||
* `ripgrep` supports many features found in `grep`, such as showing the context
|
||||
of search results, searching multiple patterns, highlighting matches with
|
||||
color and full Unicode support. Unlike GNU grep, `ripgrep` stays fast while
|
||||
supporting Unicode (which is always on).
|
||||
|
||||
In other words, use `ripgrep` if you like speed, sane defaults, fewer bugs and
|
||||
Unicode.
|
||||
|
||||
### Is it really faster than everything else?
|
||||
|
||||
Yes. A large number of benchmarks with detailed analysis for each is
|
||||
[available on my blog](http://blog.burntsushi.net/ripgrep/).
|
||||
|
||||
Summarizing, `ripgrep` is fast because:
|
||||
|
||||
* It is built on top of
|
||||
[Rust's regex engine](https://github.com/rust-lang-nursery/regex).
|
||||
Rust's regex engine uses finite automata, SIMD and aggressive literal
|
||||
optimizations to make searching very fast.
|
||||
* Rust's regex library maintains performance with full Unicode support by
|
||||
building UTF-8 decoding directly into its deterministic finite automaton
|
||||
engine.
|
||||
* It supports searching with either memory maps or by searching incrementally
|
||||
with an intermediate buffer. The former is better for single files and the
|
||||
latter is better for large directories. `ripgrep` chooses the best searching
|
||||
strategy for you automatically.
|
||||
* Applies your ignore patterns in `.gitignore` files using a
|
||||
[`RegexSet`](https://doc.rust-lang.org/regex/regex/struct.RegexSet.html).
|
||||
That means a single file path can be matched against multiple glob patterns
|
||||
simultaneously.
|
||||
* Uses a Chase-Lev work-stealing queue for quickly distributing work to
|
||||
multiple threads.
|
||||
|
||||
### Installation
|
||||
|
||||
The binary name for `ripgrep` is `rg`.
|
||||
|
||||
[Binaries for `ripgrep` are available for Windows, Mac and
|
||||
Linux.](https://github.com/BurntSushi/ripgrep/releases) Linux binaries are
|
||||
static executables. Windows binaries are available either as built with MinGW
|
||||
(GNU) or with Microsoft Visual C++ (MSVC). When possible, prefer MSVC over GNU,
|
||||
but you'll need to have the
|
||||
[Microsoft Visual C++ Build
|
||||
Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools)
|
||||
installed.
|
||||
|
||||
If you're a **Homebrew** user, then you can install it with a custom formula
|
||||
(N.B. `ripgrep` isn't actually in Homebrew yet. This just installs the binary
|
||||
directly):
|
||||
|
||||
```
|
||||
$ brew install https://raw.githubusercontent.com/BurntSushi/ripgrep/master/pkg/brew/ripgrep.rb
|
||||
```
|
||||
|
||||
If you're an **Archlinux** user, then you can install `ripgrep` from the
|
||||
[`ripgrep` AUR package](https://aur.archlinux.org/packages/ripgrep/), e.g.,
|
||||
|
||||
```
|
||||
$ yaourt -S ripgrep
|
||||
```
|
||||
|
||||
If you're a **Rust programmer**, `ripgrep` can be installed with `cargo`:
|
||||
|
||||
```
|
||||
$ cargo install ripgrep
|
||||
```
|
||||
|
||||
`ripgrep` isn't currently in any other package repositories.
|
||||
[I'd like to change that](https://github.com/BurntSushi/ripgrep/issues/10).
|
||||
|
||||
### Whirlwind tour
|
||||
|
||||
The command line usage of `ripgrep` doesn't differ much from other tools that
|
||||
perform a similar function, so you probably already know how to use `ripgrep`.
|
||||
The full details can be found in `rg --help`, but let's go on a whirlwind tour.
|
||||
|
||||
`ripgrep` detects when its printing to a terminal, and will automatically
|
||||
colorize your output and show line numbers, just like The Silver Searcher.
|
||||
Coloring works on Windows too! Colors can be controlled more granularly with
|
||||
the `--color` flag.
|
||||
|
||||
One last thing before we get started: `ripgrep` assumes UTF-8 *everywhere*. It
|
||||
can still search files that are invalid UTF-8 (like, say, latin-1), but it will
|
||||
simply not work on UTF-16 encoded files or other more exotic encodings.
|
||||
[Support for other encodings may
|
||||
happen.](https://github.com/BurntSushi/ripgrep/issues/1)
|
||||
|
||||
To recursively search the current directory, while respecting all `.gitignore`
|
||||
files, ignore hidden files and directories and skip binary files:
|
||||
|
||||
```
|
||||
$ rg foobar
|
||||
```
|
||||
|
||||
The above command also respects all `.rgignore` files, including in parent
|
||||
directories. `.rgignore` files can be used when `.gitignore` files are
|
||||
insufficient. In all cases, `.rgignore` patterns take precedence over
|
||||
`.gitignore`.
|
||||
|
||||
To ignore all ignore files, use `-u`. To additionally search hidden files
|
||||
and directories, use `-uu`. To additionally search binary files, use `-uuu`.
|
||||
(In other words, "search everything, dammit!") In particular, `rg -uuu` is
|
||||
equivalent to `grep -a -r`.
|
||||
|
||||
```
|
||||
$ rg -uu foobar # equivalent to `grep -r`
|
||||
$ rg -uuu foobar # equivalent to `grep -a -r`
|
||||
```
|
||||
|
||||
(Tip: If your ignore files aren't being adhered to like you expect, run your
|
||||
search with the `--debug` flag.)
|
||||
|
||||
Make the search case insensitive with `-i`, invert the search with `-v` or
|
||||
show the 2 lines before and after every search result with `-C2`.
|
||||
|
||||
Force all matches to be surrounded by word boundaries with `-w`.
|
||||
|
||||
Search and replace (find first and last names and swap them):
|
||||
|
||||
```
|
||||
$ rg '([A-Z][a-z]+)\s+([A-Z][a-z]+)' --replace '$2, $1'
|
||||
```
|
||||
|
||||
Named groups are supported:
|
||||
|
||||
```
|
||||
$ rg '(?P<first>[A-Z][a-z]+)\s+(?P<last>[A-Z][a-z]+)' --replace '$last, $first'
|
||||
```
|
||||
|
||||
Up the ante with full Unicode support, by matching any uppercase Unicode letter
|
||||
followed by any sequence of lowercase Unicode letters (good luck doing this
|
||||
with other search tools!):
|
||||
|
||||
```
|
||||
$ rg '(\p{Lu}\p{Ll}+)\s+(\p{Lu}\p{Ll}+)' --replace '$2, $1'
|
||||
```
|
||||
|
||||
Search only files matching a particular glob:
|
||||
|
||||
```
|
||||
$ rg foo -g 'README.*'
|
||||
```
|
||||
|
||||
<!--*-->
|
||||
|
||||
Or exclude files matching a particular glob:
|
||||
|
||||
```
|
||||
$ rg foo -g '!*.min.js'
|
||||
```
|
||||
|
||||
Search only HTML and CSS files:
|
||||
|
||||
```
|
||||
$ rg -thtml -tcss foobar
|
||||
```
|
||||
|
||||
Search everything except for Javascript files:
|
||||
|
||||
```
|
||||
$ rg -Tjs foobar
|
||||
```
|
||||
|
||||
To see a list of types supported, run `rg --type-list`. To add a new type, use
|
||||
`--type-add`:
|
||||
|
||||
```
|
||||
$ rg --type-add 'foo:*.foo,*.foobar'
|
||||
```
|
||||
|
||||
The type `foo` will now match any file ending with the `.foo` or `.foobar`
|
||||
extensions.
|
||||
|
||||
### Building
|
||||
|
||||
`ripgrep` is written in Rust, so you'll need to grab a
|
||||
[Rust installation](https://www.rust-lang.org/) in order to compile it.
|
||||
`ripgrep` compiles with Rust 1.9 (stable) or newer. Building is easy:
|
||||
|
||||
```
|
||||
$ git clone git://github.com/BurntSushi/ripgrep
|
||||
$ cd ripgrep
|
||||
$ cargo build --release
|
||||
$ ./target/release/rg --version
|
||||
0.1.3
|
||||
```
|
||||
|
||||
If you have a Rust nightly compiler, then you can enable optional SIMD
|
||||
acceleration like so:
|
||||
|
||||
```
|
||||
RUSTFLAGS="-C target-cpu=native" cargo build --release --features simd-accel
|
||||
```
|
||||
|
||||
### Running tests
|
||||
|
||||
`ripgrep` is relatively well tested, including both unit tests and integration
|
||||
tests. To run the full test suite, use:
|
||||
|
||||
```
|
||||
$ cargo test
|
||||
```
|
||||
|
||||
from the repository root.
|
11
README.md
11
README.md
@@ -1,5 +1,6 @@
|
||||
rep
|
||||
---
|
||||
A faster `grep`, written in Rust using the
|
||||
[`regex`](https://github.com/rust-lang-nursery/regex)
|
||||
crate.
|
||||
**UNDER DEVELOPMENT.**
|
||||
|
||||
ripgrep (rg)
|
||||
------------
|
||||
ripgrep combines the usability of the silver searcher with the raw speed of
|
||||
grep.
|
||||
|
23
appveyor.yml
23
appveyor.yml
@@ -2,27 +2,22 @@ environment:
|
||||
global:
|
||||
PROJECT_NAME: ripgrep
|
||||
matrix:
|
||||
# Nightly channel
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
|
||||
# Install Rust and Cargo
|
||||
# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml)
|
||||
install:
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/channel-rust-stable"
|
||||
- ps: $env:RUST_VERSION = Get-Content channel-rust-stable | select -first 1 | %{$_.split('-')[1]}
|
||||
- if NOT "%CHANNEL%" == "stable" set RUST_VERSION=%CHANNEL%
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:RUST_VERSION}-${env:TARGET}.exe"
|
||||
- rust-%RUST_VERSION%-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
||||
- if "%TARGET%" == "i686-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw32\bin
|
||||
- if "%TARGET%" == "x86_64-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw64\bin
|
||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
||||
- rustup-init.exe -y --default-host %TARGET%
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- if defined MSYS2_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS2_BITS%\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
@@ -57,7 +52,7 @@ deploy:
|
||||
# channel to use to produce the release artifacts
|
||||
# NOTE make sure you only release *once* per target
|
||||
# TODO you may want to pick a different channel
|
||||
CHANNEL: nightly
|
||||
CHANNEL: stable
|
||||
appveyor_repo_tag: true
|
||||
|
||||
branches:
|
||||
|
5
benches/README.md
Normal file
5
benches/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
These are internal microbenchmarks for tracking the peformance of individual
|
||||
components inside of ripgrep. At the moment, they aren't heavily used.
|
||||
|
||||
For performance benchmarks of ripgrep proper, see the sibling `benchsuite`
|
||||
directory.
|
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''
|
||||
benchsuite is a benchmark runner for comparing command line search tools.
|
||||
@@ -10,6 +10,7 @@ import os
|
||||
import os.path as path
|
||||
from multiprocessing import cpu_count
|
||||
import re
|
||||
import shutil
|
||||
import statistics
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -23,6 +24,7 @@ import time
|
||||
|
||||
SUBTITLES_DIR = 'subtitles'
|
||||
SUBTITLES_EN_NAME = 'OpenSubtitles2016.raw.en'
|
||||
SUBTITLES_EN_NAME_SAMPLE = 'OpenSubtitles2016.raw.sample.en'
|
||||
SUBTITLES_EN_NAME_GZ = '%s.gz' % SUBTITLES_EN_NAME
|
||||
SUBTITLES_EN_URL = 'http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitles2016.raw.en.gz'
|
||||
SUBTITLES_RU_NAME = 'OpenSubtitles2016.raw.ru'
|
||||
@@ -32,13 +34,29 @@ SUBTITLES_RU_URL = 'http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitl
|
||||
LINUX_DIR = 'linux'
|
||||
LINUX_CLONE = 'git://github.com/BurntSushi/linux'
|
||||
|
||||
# Grep takes locale settings from the environment. There is a *substantial*
|
||||
# performance impact for enabling Unicode, so we need to handle this explicitly
|
||||
# in our benchmarks.
|
||||
GREP_ASCII = {'LC_ALL': 'C'}
|
||||
GREP_UNICODE = {'LC_ALL': 'en_US.UTF-8'}
|
||||
|
||||
# Sift tries really hard to search everything by default. In our code search
|
||||
# benchmarks, we don't want that.
|
||||
SIFT = [
|
||||
'sift',
|
||||
'--binary-skip',
|
||||
'--exclude-files', '.*',
|
||||
'--exclude-files', '*.pdf',
|
||||
]
|
||||
|
||||
|
||||
def bench_linux_literal_default(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a literal using *default* settings.
|
||||
|
||||
This is a purposefully unfair benchmark for use in performance
|
||||
analysis, but it is pedagogically useful.
|
||||
analysis, but it is pedagogically useful to demonstrate how
|
||||
default behaviors differ.
|
||||
'''
|
||||
require(suite_dir, 'linux')
|
||||
cwd = path.join(suite_dir, LINUX_DIR)
|
||||
@@ -48,8 +66,6 @@ def bench_linux_literal_default(suite_dir):
|
||||
kwargs['cwd'] = cwd
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
# N.B. This is a purposefully unfair benchmark for illustrative purposes
|
||||
# of how the default modes for each search tool differ.
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', pat]),
|
||||
mkcmd('ag', ['ag', pat]),
|
||||
@@ -57,10 +73,12 @@ def bench_linux_literal_default(suite_dir):
|
||||
# doesn't read gitignore files. Instead, it has a file whitelist
|
||||
# that happens to match up exactly with the gitignores for this search.
|
||||
mkcmd('ucg', ['ucg', pat]),
|
||||
mkcmd('git grep', ['git', 'grep', pat], env={'LC_ALL': 'C'}),
|
||||
# I guess setting LC_ALL=en_US.UTF-8 probably isn't necessarily the
|
||||
# default, but I'd guess it to be on most desktop systems.
|
||||
mkcmd('pt', ['pt', pat]),
|
||||
# sift reports an extra line here for a binary file matched.
|
||||
mkcmd('sift', ['sift', pat]),
|
||||
mkcmd('git grep', ['git', 'grep', pat], env={'LC_ALL': 'en_US.UTF-8'}),
|
||||
])
|
||||
|
||||
|
||||
@@ -69,8 +87,9 @@ def bench_linux_literal(suite_dir):
|
||||
Benchmark the speed of a literal, attempting to be fair.
|
||||
|
||||
This tries to use the minimum set of options available in all tools
|
||||
to test how fast they are. For example, it makes sure there is no
|
||||
case insensitive matching and that line numbers are computed.
|
||||
to test how fast they are. For example, it makes sure there is
|
||||
no case insensitive matching and that line numbers are computed
|
||||
(because some tools don't permit disabling line numbers).
|
||||
'''
|
||||
require(suite_dir, 'linux')
|
||||
cwd = path.join(suite_dir, LINUX_DIR)
|
||||
@@ -81,19 +100,16 @@ def bench_linux_literal(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', pat]),
|
||||
mkcmd('rg-novcs-mmap', ['rg', '--mmap', '--no-ignore', '-n', pat]),
|
||||
mkcmd('ag', ['ag', '-s', pat]),
|
||||
mkcmd('ag-novcs', ['ag', '--skip-vcs-ignores', '-s', pat]),
|
||||
mkcmd('ucg', ['ucg', '--nosmart-case', pat]),
|
||||
mkcmd('git grep', [
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('rg (ignore) (mmap)', ['rg', '-n', '--mmap', pat]),
|
||||
mkcmd('ag (ignore) (mmap)', ['ag', '-s', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd('git grep (ignore)', [
|
||||
'git', 'grep', '-I', '-n', pat,
|
||||
], env={'LC_ALL': 'C'}),
|
||||
mkcmd('pt', ['pt', pat]),
|
||||
mkcmd('sift', [
|
||||
'sift', '-n', '--binary-skip', '--exclude-files', '.*', pat,
|
||||
]),
|
||||
mkcmd('rg (whitelist)', ['rg', '-n', '--no-ignore', '-tall', pat]),
|
||||
mkcmd('ucg (whitelist)', ['ucg', '--nosmart-case', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -113,23 +129,22 @@ def bench_linux_literal_casei(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', '-i', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', '-i', pat]),
|
||||
mkcmd('rg-novcs-mmap', [
|
||||
'rg', '--mmap', '--no-ignore', '-n', '-i', pat,
|
||||
]),
|
||||
mkcmd('ag', ['ag', '-i', pat]),
|
||||
mkcmd('ag-novcs', ['ag', '--skip-vcs-ignores', '-i', pat]),
|
||||
mkcmd('ucg', ['ucg', '-i', pat]),
|
||||
mkcmd('git grep', [
|
||||
mkcmd('rg (ignore)', ['rg', '-n', '-i', pat]),
|
||||
mkcmd('rg (ignore) (mmap)', ['rg', '-n', '-i', '--mmap', pat]),
|
||||
mkcmd('ag (ignore) (mmap)', ['ag', '-i', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', '-i', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '-i', '--git', pat]),
|
||||
# It'd technically be more appropriate to set LC_ALL=en_US.UTF-8 here,
|
||||
# since that is certainly what ripgrep is doing, but this is for an
|
||||
# ASCII literal, so we should give `git grep` all the opportunity to
|
||||
# do its best.
|
||||
mkcmd('git grep (ignore)', [
|
||||
'git', 'grep', '-I', '-n', '-i', pat,
|
||||
], env={'LC_ALL': 'C'}),
|
||||
# sift yields more matches than it should here. Specifically, it gets
|
||||
# matches in Module.symvers and System.map in the repo root. Both of
|
||||
# those files show up in the repo root's .gitignore file.
|
||||
mkcmd('sift', [
|
||||
'sift', '-n', '--binary-skip', '--exclude-files', '.*', '-i', pat,
|
||||
mkcmd('rg (whitelist)', [
|
||||
'rg', '-n', '-i', '--no-ignore', '-tall', pat,
|
||||
]),
|
||||
mkcmd('ucg (whitelist)', ['ucg', '-i', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -149,20 +164,17 @@ def bench_linux_re_literal_suffix(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', pat]),
|
||||
mkcmd('rg-novcs-mmap', ['rg', '--mmap', '--no-ignore', '-n', pat]),
|
||||
mkcmd('ag', ['ag', '-s', pat]),
|
||||
mkcmd('ag-novcs', ['ag', '--skip-vcs-ignores', '-s', pat]),
|
||||
mkcmd('ucg', ['ucg', '--nosmart-case', pat]),
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('ag (ignore)', ['ag', '-s', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', '-e', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep',
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
env={'LC_ALL': 'C'},
|
||||
),
|
||||
mkcmd('sift', [
|
||||
'sift', '-n', '--binary-skip', '--exclude-files', '.*', pat,
|
||||
]),
|
||||
mkcmd('rg (whitelist)', ['rg', '-n', '--no-ignore', '-tall', pat]),
|
||||
mkcmd('ucg (whitelist)', ['ucg', '--nosmart-case', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -182,22 +194,19 @@ def bench_linux_word(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', '-w', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', '-w', pat]),
|
||||
mkcmd('rg-novcs-mmap', [
|
||||
'rg', '--mmap', '--no-ignore', '-n', '-w', pat,
|
||||
]),
|
||||
mkcmd('ag', ['ag', '-s', '-w', pat]),
|
||||
mkcmd('ag-novcs', ['ag', '--skip-vcs-ignores', '-s', '-w', pat]),
|
||||
mkcmd('ucg', ['ucg', '--nosmart-case', '-w', pat]),
|
||||
mkcmd('rg (ignore)', ['rg', '-n', '-w', pat]),
|
||||
mkcmd('ag (ignore)', ['ag', '-s', '-w', pat]),
|
||||
mkcmd('pt (ignore)', ['pt', '-w', pat]),
|
||||
mkcmd('sift (ignore)', SIFT + ['-n', '-w', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep',
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', '-w', pat],
|
||||
env={'LC_ALL': 'C'},
|
||||
),
|
||||
mkcmd('sift', [
|
||||
'sift', '-n', '--binary-skip', '--exclude-files', '.*', '-w', pat,
|
||||
mkcmd('rg (whitelist)', [
|
||||
'rg', '-n', '-w', '--no-ignore', '-tall', pat,
|
||||
]),
|
||||
mkcmd('ucg (whitelist)', ['ucg', '--nosmart-case', '-w', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -205,7 +214,8 @@ def bench_linux_unicode_greek(suite_dir):
|
||||
'''
|
||||
Benchmark matching of a Unicode category.
|
||||
|
||||
Only three tools (ripgrep, sift and pt) support this.
|
||||
Only three tools (ripgrep, sift and pt) support this. We omit
|
||||
pt because it is too slow.
|
||||
'''
|
||||
require(suite_dir, 'linux')
|
||||
cwd = path.join(suite_dir, LINUX_DIR)
|
||||
@@ -217,15 +227,8 @@ def bench_linux_unicode_greek(suite_dir):
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
# sift tries to search a bunch of PDF files and clutters up the
|
||||
# results, even though --binary-skip is provided. They are excluded
|
||||
# here explicitly, but don't have a measurable impact on performance.
|
||||
mkcmd('sift', [
|
||||
'sift', '-n', '--binary-skip',
|
||||
'--exclude-files', '.*',
|
||||
'--exclude-files', '*.pdf',
|
||||
pat,
|
||||
]),
|
||||
mkcmd('pt', ['pt', '-e', pat]),
|
||||
mkcmd('sift', SIFT + ['-n', '--git', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -245,15 +248,8 @@ def bench_linux_unicode_greek_casei(suite_dir):
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', '-i', pat]),
|
||||
# sift tries to search a bunch of PDF files and clutters up the
|
||||
# results, even though --binary-skip is provided. They are excluded
|
||||
# here explicitly, but don't have a measurable impact on performance.
|
||||
mkcmd('sift', [
|
||||
'sift', '-n', '--binary-skip',
|
||||
'--exclude-files', '.*',
|
||||
'--exclude-files', '*.pdf',
|
||||
pat,
|
||||
]),
|
||||
mkcmd('pt', ['pt', '-i', '-e', pat]),
|
||||
mkcmd('sift', SIFT + ['-n', '-i', '--git', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -274,30 +270,26 @@ def bench_linux_unicode_word(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
mkcmd('rg (no Unicode)', ['rg', '-n', '(?-u)' + pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', pat]),
|
||||
mkcmd('rg-novcs-mmap', [
|
||||
'rg', '--mmap', '--no-ignore', '-n', pat,
|
||||
]),
|
||||
mkcmd('ag (no Unicode)', ['ag', '-s', pat]),
|
||||
mkcmd('ag-novcs (no Unicode)', [
|
||||
'ag', '--skip-vcs-ignores', '-s', pat,
|
||||
]),
|
||||
mkcmd('ucg (no Unicode)', ['ucg', '--nosmart-case', pat]),
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('rg (ignore) (ASCII)', ['rg', '-n', '(?-u)' + pat]),
|
||||
mkcmd('ag (ignore) (ASCII)', ['ag', '-s', pat]),
|
||||
mkcmd('pt (ignore) (ASCII)', ['pt', '-e', pat]),
|
||||
mkcmd('sift (ignore) (ASCII)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep',
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
env={'LC_ALL': 'en_US.UTF-8'},
|
||||
),
|
||||
mkcmd(
|
||||
'git grep (no Unicode)',
|
||||
'git grep (ignore) (ASCII)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
env={'LC_ALL': 'C'},
|
||||
),
|
||||
mkcmd('sift (no Unicode)', [
|
||||
'sift', '-n', '--binary-skip', '--exclude-files', '.*', pat,
|
||||
mkcmd('rg (whitelist)', ['rg', '-n', '--no-ignore', '-tall', pat]),
|
||||
mkcmd('rg (whitelist) (ASCII)', [
|
||||
'rg', '-n', '--no-ignore', '-tall', '(?-u)' + pat,
|
||||
]),
|
||||
mkcmd('ucg (ASCII)', ['ucg', '--nosmart-case', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -319,30 +311,26 @@ def bench_linux_no_literal(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', pat]),
|
||||
mkcmd('rg (no Unicode)', ['rg', '-n', '(?-u)' + pat]),
|
||||
mkcmd('rg-novcs (no Unicode)', [
|
||||
'rg', '--no-ignore', '-n', '(?-u)' + pat,
|
||||
]),
|
||||
mkcmd('ag (no Unicode)', ['ag', '-s', pat]),
|
||||
mkcmd('ag-novcs (no Unicode)', [
|
||||
'ag', '--skip-vcs-ignores', '-s', pat,
|
||||
]),
|
||||
mkcmd('ucg (no Unicode)', ['ucg', '--nosmart-case', pat]),
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('rg (ignore) (ASCII)', ['rg', '-n', '(?-u)' + pat]),
|
||||
mkcmd('ag (ignore) (ASCII)', ['ag', '-s', pat]),
|
||||
mkcmd('pt (ignore) (ASCII)', ['pt', '-e', pat]),
|
||||
mkcmd('sift (ignore) (ASCII)', SIFT + ['-n', '--git', pat]),
|
||||
mkcmd(
|
||||
'git grep',
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
env={'LC_ALL': 'en_US.UTF-8'},
|
||||
),
|
||||
mkcmd(
|
||||
'git grep (no Unicode)',
|
||||
'git grep (ignore) (ASCII)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
env={'LC_ALL': 'C'},
|
||||
),
|
||||
mkcmd('sift (no Unicode)', [
|
||||
'sift', '-n', '--binary-skip', '--exclude-files', '.*', pat,
|
||||
mkcmd('rg (whitelist)', ['rg', '-n', '--no-ignore', '-tall', pat]),
|
||||
mkcmd('rg (whitelist) (ASCII)', [
|
||||
'rg', '-n', '--no-ignore', '-tall', '(?-u)' + pat,
|
||||
]),
|
||||
mkcmd('ucg (whitelist) (ASCII)', ['ucg', '--nosmart-case', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -364,21 +352,15 @@ def bench_linux_alternates(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', pat]),
|
||||
mkcmd('rg-novcs-mmap', [
|
||||
'rg', '--mmap', '--no-ignore', '-n', pat,
|
||||
]),
|
||||
mkcmd('ag', ['ag', '-s', pat]),
|
||||
mkcmd('ag-novcs', [
|
||||
'ag', '--skip-vcs-ignores', '-s', pat,
|
||||
]),
|
||||
mkcmd('ucg', ['ucg', '--nosmart-case', pat]),
|
||||
mkcmd('rg (ignore)', ['rg', '-n', pat]),
|
||||
mkcmd('ag (ignore)', ['ag', '-s', pat]),
|
||||
mkcmd(
|
||||
'git grep',
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', pat],
|
||||
env={'LC_ALL': 'C'},
|
||||
),
|
||||
mkcmd('rg (whitelist)', ['rg', '--no-ignore', '-n', pat]),
|
||||
mkcmd('ucg (whitelist)', ['ucg', '--nosmart-case', pat]),
|
||||
])
|
||||
|
||||
|
||||
@@ -393,36 +375,336 @@ def bench_linux_alternates_casei(suite_dir):
|
||||
return Command(*args, **kwargs)
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
mkcmd('rg', ['rg', '-n', '-i', pat]),
|
||||
mkcmd('rg-novcs', ['rg', '--no-ignore', '-n', '-i', pat]),
|
||||
mkcmd('rg-novcs-mmap', [
|
||||
'rg', '--mmap', '--no-ignore', '-n', '-i', pat,
|
||||
]),
|
||||
mkcmd('ag', ['ag', '-i', pat]),
|
||||
mkcmd('ag-novcs', [
|
||||
'ag', '--skip-vcs-ignores', '-i', pat,
|
||||
]),
|
||||
mkcmd('ucg', ['ucg', '-i', pat]),
|
||||
mkcmd('rg (ignore)', ['rg', '-n', '-i', pat]),
|
||||
mkcmd('ag (ignore)', ['ag', '-i', pat]),
|
||||
mkcmd(
|
||||
'git grep',
|
||||
'git grep (ignore)',
|
||||
['git', 'grep', '-E', '-I', '-n', '-i', pat],
|
||||
env={'LC_ALL': 'C'},
|
||||
),
|
||||
mkcmd('rg (whitelist)', ['rg', '--no-ignore', '-n', '-i', pat]),
|
||||
mkcmd('ucg (whitelist)', ['ucg', '-i', pat]),
|
||||
])
|
||||
|
||||
|
||||
# BREADCRUMBS(burntsushi): We should benchmark an alternation for `linux` as
|
||||
# well.
|
||||
|
||||
def bench_sherlock(suite_dir):
|
||||
'TODO: Fix this and add more single file benchmarks.'
|
||||
def bench_subtitles_en_literal(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of an ASCII string literal.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME)
|
||||
pat = 'Sherlock'
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = 'Sherlock Holmes'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', pat, en]),
|
||||
Command('grep', ['grep', '-a', pat, en])
|
||||
Command('pt', ['pt', '-N', pat, en]),
|
||||
Command('sift', ['sift', pat, en]),
|
||||
Command('grep', ['grep', '-a', pat, en], env=GREP_ASCII),
|
||||
Command('rg (lines)', ['rg', '-n', pat, en]),
|
||||
Command('ag (lines)', ['ag', '-s', pat, en]),
|
||||
Command('ucg (lines)', ['ucg', '--nosmart-case', pat, en]),
|
||||
Command('pt (lines)', ['pt', pat, en]),
|
||||
Command('sift (lines)', ['sift', '-n', pat, en]),
|
||||
Command('grep (lines)', ['grep', '-an', pat, en], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_en_literal_casei(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a Unicode-y string case insensitively.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = 'Sherlock Holmes'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', '-i', pat, en]),
|
||||
Command('grep', ['grep', '-ai', pat, en], env=GREP_UNICODE),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-ai', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg (lines)', ['rg', '-n', '-i', pat, en]),
|
||||
Command('ag (lines) (ASCII)', ['ag', '-i', pat, en]),
|
||||
Command('ucg (lines) (ASCII)', ['ucg', '-i', pat, en]),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_en_literal_word(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of finding a literal inside word boundaries.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = 'Sherlock Holmes'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg (ASCII)', [
|
||||
'rg', '-n', r'(?-u:\b)' + pat + r'(?-u:\b)', en,
|
||||
]),
|
||||
Command('ag (ASCII)', ['ag', '-sw', pat, en]),
|
||||
Command('ucg (ASCII)', ['ucg', '--nosmart-case', pat, en]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-anw', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg', ['rg', '-nw', pat, en]),
|
||||
Command('grep', ['grep', '-anw', pat, en], env=GREP_UNICODE),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_en_alternate(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a set of alternate literals.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = '|'.join([
|
||||
'Sherlock Holmes',
|
||||
'John Watson',
|
||||
'Irene Adler',
|
||||
'Inspector Lestrade',
|
||||
'Professor Moriarty',
|
||||
])
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg (lines)', ['rg', '-n', pat, en]),
|
||||
Command('ag (lines)', ['ag', '-s', pat, en]),
|
||||
Command('ucg (lines)', ['ucg', '--nosmart-case', pat, en]),
|
||||
Command('grep (lines)', [
|
||||
'grep', '-E', '-an', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg', ['rg', pat, en]),
|
||||
Command('grep', [
|
||||
'grep', '-E', '-a', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_en_alternate_casei(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a set of alternate literals.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = '|'.join([
|
||||
'Sherlock Holmes',
|
||||
'John Watson',
|
||||
'Irene Adler',
|
||||
'Inspector Lestrade',
|
||||
'Professor Moriarty',
|
||||
])
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('ag (ASCII)', ['ag', '-s', '-i', pat, en]),
|
||||
Command('ucg (ASCII)', ['ucg', '-i', pat, en]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-ani', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg', ['rg', '-n', '-i', pat, en]),
|
||||
Command('grep', ['grep', '-E', '-ani', pat, en], env=GREP_UNICODE),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_en_surrounding_words(suite_dir):
|
||||
'''
|
||||
Benchmark a more complex regex with an inner literal.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = r'\w+\s+Holmes\s+\w+'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', '-n', pat, en]),
|
||||
Command('grep', ['grep', '-E', '-an', pat, en], env=GREP_UNICODE),
|
||||
Command('rg (ASCII)', ['rg', '-n', '(?-u)' + pat, en]),
|
||||
Command('ag (ASCII)', ['ag', '-s', pat, en]),
|
||||
Command('ucg (ASCII)', ['ucg', '--nosmart-case', pat, en]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-an', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_en_no_literal(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a regex with no literals.
|
||||
|
||||
Note that we don't even try to run grep with Unicode support
|
||||
on this one. While it should eventually get the right answer,
|
||||
I killed it after it had already been running for two minutes
|
||||
and showed no signs of finishing soon.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
en = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_EN_NAME_SAMPLE)
|
||||
pat = r'\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', '-n', pat, en]),
|
||||
Command('rg (ASCII)', ['rg', '-n', '(?-u)' + pat, en]),
|
||||
Command('ag (ASCII)', ['ag', '-s', pat, en]),
|
||||
Command('ucg (ASCII)', ['ucg', '--nosmart-case', pat, en]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-an', pat, en,
|
||||
], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_literal(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a Unicode-y string literal.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-ru')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = 'Шерлок Холмс' # Sherlock Holmes
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', pat, ru]),
|
||||
Command('pt', ['pt', '-N', pat, ru]),
|
||||
Command('sift', ['sift', pat, ru]),
|
||||
Command('grep', ['grep', '-a', pat, ru], env=GREP_ASCII),
|
||||
Command('rg (lines)', ['rg', '-n', pat, ru]),
|
||||
Command('ag (lines)', ['ag', '-s', pat, ru]),
|
||||
Command('ucg (lines)', ['ucg', '--nosmart-case', pat, ru]),
|
||||
Command('pt (lines)', ['pt', pat, ru]),
|
||||
Command('sift (lines)', ['sift', '-n', pat, ru]),
|
||||
Command('grep (lines)', ['grep', '-an', pat, ru], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_literal_casei(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a Unicode-y string case insensitively.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-ru')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = 'Шерлок Холмс' # Sherlock Holmes
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', '-i', pat, ru]),
|
||||
Command('grep', ['grep', '-ai', pat, ru], env=GREP_UNICODE),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-ai', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg (lines)', ['rg', '-n', '-i', pat, ru]),
|
||||
Command('ag (lines) (ASCII)', ['ag', '-i', pat, ru]),
|
||||
Command('ucg (lines) (ASCII)', ['ucg', '-i', pat, ru]),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_literal_word(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of finding a literal inside word boundaries.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-ru')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = 'Шерлок Холмс' # Sherlock Holmes
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg (ASCII)', [
|
||||
'rg', '-n', r'(?-u:\b)' + pat + r'(?-u:\b)', ru,
|
||||
]),
|
||||
Command('ag (ASCII)', ['ag', '-sw', pat, ru]),
|
||||
Command('ucg (ASCII)', ['ucg', '--nosmart-case', pat, ru]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-anw', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg', ['rg', '-nw', pat, ru]),
|
||||
Command('grep', ['grep', '-anw', pat, ru], env=GREP_UNICODE),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_alternate(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a set of alternate literals.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-ru')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = '|'.join([
|
||||
'Шерлок Холмс', # Sherlock Holmes
|
||||
'Джон Уотсон', # John Watson
|
||||
'Ирен Адлер', # Irene Adler
|
||||
'инспектор Лестрейд', # Inspector Lestrade
|
||||
'профессор Мориарти', # Professor Moriarty
|
||||
])
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg (lines)', ['rg', '-n', pat, ru]),
|
||||
Command('ag (lines)', ['ag', '-s', pat, ru]),
|
||||
Command('ucg (lines)', ['ucg', '--nosmart-case', pat, ru]),
|
||||
Command('grep (lines)', [
|
||||
'grep', '-E', '-an', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg', ['rg', pat, ru]),
|
||||
Command('grep', [
|
||||
'grep', '-E', '-a', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_alternate_casei(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a set of alternate literals.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-ru')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = '|'.join([
|
||||
'Шерлок Холмс', # Sherlock Holmes
|
||||
'Джон Уотсон', # John Watson
|
||||
'Ирен Адлер', # Irene Adler
|
||||
'инспектор Лестрейд', # Inspector Lestrade
|
||||
'профессор Мориарти', # Professor Moriarty
|
||||
])
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('ag (ASCII)', ['ag', '-s', '-i', pat, ru]),
|
||||
Command('ucg (ASCII)', ['ucg', '-i', pat, ru]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-ani', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
Command('rg', ['rg', '-n', '-i', pat, ru]),
|
||||
Command('grep', ['grep', '-E', '-ani', pat, ru], env=GREP_UNICODE),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_surrounding_words(suite_dir):
|
||||
'''
|
||||
Benchmark a more complex regex with an inner literal.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-en')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = r'\w+\s+Холмс\s+\w+'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', '-n', pat, ru]),
|
||||
Command('grep', ['grep', '-E', '-an', pat, ru], env=GREP_UNICODE),
|
||||
Command('ag (ASCII)', ['ag', '-s', pat, ru]),
|
||||
Command('ucg (ASCII)', ['ucg', '--nosmart-case', pat, ru]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-an', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
def bench_subtitles_ru_no_literal(suite_dir):
|
||||
'''
|
||||
Benchmark the speed of a regex with no literals.
|
||||
|
||||
Note that we don't even try to run grep with Unicode support
|
||||
on this one. While it should eventually get the right answer,
|
||||
I killed it after it had already been running for two minutes
|
||||
and showed no signs of finishing soon.
|
||||
'''
|
||||
require(suite_dir, 'subtitles-ru')
|
||||
ru = path.join(suite_dir, SUBTITLES_DIR, SUBTITLES_RU_NAME)
|
||||
pat = r'\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}'
|
||||
|
||||
return Benchmark(pattern=pat, commands=[
|
||||
Command('rg', ['rg', '-n', pat, ru]),
|
||||
Command('rg (ASCII)', ['rg', '-n', '(?-u)' + pat, ru]),
|
||||
Command('ag (ASCII)', ['ag', '-s', pat, ru]),
|
||||
Command('ucg (ASCII)', ['ucg', '--nosmart-case', pat, ru]),
|
||||
Command('grep (ASCII)', [
|
||||
'grep', '-E', '-an', pat, ru,
|
||||
], env=GREP_ASCII),
|
||||
])
|
||||
|
||||
|
||||
@@ -444,6 +726,23 @@ class MissingDependencies(Exception):
|
||||
return 'MissingDependency(%s)' % repr(self.missing_names)
|
||||
|
||||
|
||||
class MissingCommands(Exception):
|
||||
'''
|
||||
A missing command exception.
|
||||
|
||||
This exception occurs when running a command in a benchmark
|
||||
where the command could not be found on the current system.
|
||||
|
||||
:ivar list(str) missing_names:
|
||||
The names of the command binaries that could not be found.
|
||||
'''
|
||||
def __init__(self, missing_names):
|
||||
self.missing_names = sorted(set(missing_names))
|
||||
|
||||
def __str__(self):
|
||||
return 'MissingCommands(%s)' % repr(self.missing_names)
|
||||
|
||||
|
||||
class Benchmark(object):
|
||||
'''
|
||||
A single benchmark corresponding to a grouping of commands.
|
||||
@@ -453,7 +752,8 @@ class Benchmark(object):
|
||||
'''
|
||||
|
||||
def __init__(self, name=None, pattern=None, commands=None,
|
||||
warmup_count=1, count=3, line_count=True):
|
||||
warmup_count=1, count=3, line_count=True,
|
||||
allow_missing_commands=False):
|
||||
'''
|
||||
Create a single benchmark.
|
||||
|
||||
@@ -491,15 +791,37 @@ class Benchmark(object):
|
||||
self.warmup_count = warmup_count
|
||||
self.count = count
|
||||
self.line_count = line_count
|
||||
self.allow_missing_commands = allow_missing_commands
|
||||
|
||||
def raise_if_missing(self):
|
||||
'''
|
||||
Raises a MissingCommands exception if applicable.
|
||||
|
||||
A MissingCommands exception is raised when the following
|
||||
criteria are met: 1) allow_missing_commands is False, and 2) at
|
||||
least one command in this benchmark could not be found on this
|
||||
system.
|
||||
'''
|
||||
missing_commands = \
|
||||
[c.binary_name for c in self.commands if not c.exists()]
|
||||
if not self.allow_missing_commands and len(missing_commands) > 0:
|
||||
raise MissingCommands(missing_commands)
|
||||
|
||||
def run(self):
|
||||
'''
|
||||
Runs this benchmark and returns the results.
|
||||
|
||||
:rtype: Result
|
||||
:raises:
|
||||
MissingCommands if any command doesn't exist.
|
||||
(Unless allow_missing_commands is enabled.)
|
||||
'''
|
||||
self.raise_if_missing()
|
||||
result = Result(self)
|
||||
for cmd in self.commands:
|
||||
if self.allow_missing_commands and not cmd.exists():
|
||||
# Skip this command if we're OK with it.
|
||||
continue
|
||||
# Do a warmup first.
|
||||
for _ in range(self.warmup_count):
|
||||
self.run_one(cmd)
|
||||
@@ -524,6 +846,8 @@ class Benchmark(object):
|
||||
it is the number of lines in the search output.
|
||||
:rtype: int
|
||||
'''
|
||||
if not cmd.exists():
|
||||
raise MissingCommand(cmd.cmd[0])
|
||||
cmd.kwargs['stderr'] = subprocess.DEVNULL
|
||||
if self.line_count:
|
||||
cmd.kwargs['stdout'] = subprocess.PIPE
|
||||
@@ -593,6 +917,8 @@ class Result(object):
|
||||
means = []
|
||||
for cmd in self.benchmark.commands:
|
||||
mean, _ = self.distribution_for(cmd)
|
||||
if mean is None:
|
||||
continue
|
||||
means.append((cmd, mean))
|
||||
return min(means, key=lambda tup: tup[1])[0]
|
||||
|
||||
@@ -615,16 +941,18 @@ class Result(object):
|
||||
'''
|
||||
Returns the distribution (mean +/- std) of the given command.
|
||||
|
||||
If there are no samples for this command (i.e., it was skipped),
|
||||
then return ``(None, None)``.
|
||||
|
||||
:rtype: (float, float)
|
||||
:returns:
|
||||
A tuple containing the mean and standard deviation, in that
|
||||
order.
|
||||
'''
|
||||
mean = statistics.mean(
|
||||
s['duration'] for s in self.samples_for(cmd))
|
||||
stdev = statistics.stdev(
|
||||
s['duration'] for s in self.samples_for(cmd))
|
||||
return mean, stdev
|
||||
samples = list(s['duration'] for s in self.samples_for(cmd))
|
||||
if len(samples) == 0:
|
||||
return None, None
|
||||
return statistics.mean(samples), statistics.stdev(samples)
|
||||
|
||||
|
||||
class Command(object):
|
||||
@@ -654,6 +982,15 @@ class Command(object):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
def exists(self):
|
||||
'Returns true if and only if this command exists.'
|
||||
return shutil.which(self.binary_name) is not None
|
||||
|
||||
@property
|
||||
def binary_name(self):
|
||||
'Return the binary name of this command.'
|
||||
return self.cmd[0]
|
||||
|
||||
def run(self):
|
||||
'''
|
||||
Runs this command and returns its status.
|
||||
@@ -723,6 +1060,7 @@ def download_subtitles_en(suite_dir):
|
||||
subtitle_dir = path.join(suite_dir, SUBTITLES_DIR)
|
||||
en_path_gz = path.join(subtitle_dir, SUBTITLES_EN_NAME_GZ)
|
||||
en_path = path.join(subtitle_dir, SUBTITLES_EN_NAME)
|
||||
en_path_sample = path.join(subtitle_dir, SUBTITLES_EN_NAME_SAMPLE)
|
||||
|
||||
if not os.path.isdir(subtitle_dir):
|
||||
os.makedirs(subtitle_dir)
|
||||
@@ -730,12 +1068,19 @@ def download_subtitles_en(suite_dir):
|
||||
if not os.path.exists(en_path_gz):
|
||||
run_cmd(['curl', '-LO', SUBTITLES_EN_URL], cwd=subtitle_dir)
|
||||
run_cmd(['gunzip', en_path_gz], cwd=subtitle_dir)
|
||||
if not os.path.exists(en_path_sample):
|
||||
# Get a sample roughly the same size as the Russian corpus so that
|
||||
# benchmarks finish in a reasonable time.
|
||||
with open(path.join(subtitle_dir, en_path_sample), 'wb+') as f:
|
||||
run_cmd(
|
||||
['head', '-n', '32722372', en_path],
|
||||
cwd=subtitle_dir, stdout=f)
|
||||
|
||||
|
||||
def has_subtitles_en(suite_dir):
|
||||
'Returns true if English subtitles have been downloaded.'
|
||||
subtitle_dir = path.join(suite_dir, SUBTITLES_DIR)
|
||||
return path.exists(path.join(subtitle_dir, SUBTITLES_EN_NAME))
|
||||
return path.exists(path.join(subtitle_dir, SUBTITLES_EN_NAME_SAMPLE))
|
||||
|
||||
|
||||
def download_subtitles_ru(suite_dir):
|
||||
@@ -770,7 +1115,7 @@ def download(suite_dir, choices):
|
||||
A list of corpora to download. Available choices are:
|
||||
all, linux, subtitles-en, subtitles-ru.
|
||||
'''
|
||||
for choice in args.download:
|
||||
for choice in choices:
|
||||
if choice == 'linux':
|
||||
download_linux(suite_dir)
|
||||
elif choice == 'subtitles-en':
|
||||
@@ -786,7 +1131,9 @@ def download(suite_dir, choices):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def collect_benchmarks(suite_dir, filter_pat=None):
|
||||
def collect_benchmarks(suite_dir, filter_pat=None,
|
||||
allow_missing_commands=False,
|
||||
warmup_iter=1, bench_iter=3):
|
||||
'''
|
||||
Return an iterable of all runnable benchmarks.
|
||||
|
||||
@@ -808,6 +1155,11 @@ def collect_benchmarks(suite_dir, filter_pat=None):
|
||||
continue
|
||||
try:
|
||||
benchmark = globals()[fun](suite_dir)
|
||||
benchmark.name = name
|
||||
benchmark.warmup_count = warmup_iter
|
||||
benchmark.count = bench_iter
|
||||
benchmark.allow_missing_commands = allow_missing_commands
|
||||
benchmark.raise_if_missing()
|
||||
except MissingDependencies as e:
|
||||
eprint(
|
||||
'missing: %s, skipping benchmark %s (try running with: %s)' % (
|
||||
@@ -815,24 +1167,32 @@ def collect_benchmarks(suite_dir, filter_pat=None):
|
||||
name,
|
||||
' '.join(['--download %s' % n for n in e.missing_names]),
|
||||
))
|
||||
except MissingCommands as e:
|
||||
fmt = 'missing commands: %s, skipping benchmark %s ' \
|
||||
'(run with --allow-missing to run incomplete benchmarks)'
|
||||
eprint(fmt % (', '.join(e.missing_names), name))
|
||||
continue
|
||||
benchmark.name = name
|
||||
yield benchmark
|
||||
|
||||
|
||||
def main():
|
||||
download_choices = ['all', 'linux', 'subtitles-en', 'subtitles-ru']
|
||||
p = argparse.ArgumentParser('Command line search tool benchmark suite.')
|
||||
p.add_argument(
|
||||
'--dir', metavar='PATH', default=os.getcwd(),
|
||||
help='The directory in which to download data and perform searches.')
|
||||
p.add_argument(
|
||||
'--download', metavar='CORPUS', action='append',
|
||||
choices=['all', 'linux', 'subtitles-en', 'subtitles-ru'],
|
||||
choices=download_choices,
|
||||
help='Download and prepare corpus data, then exit without running '
|
||||
'any benchmarks. Note that this command is intended to be '
|
||||
'idempotent. WARNING: This downloads over a gigabyte of data, '
|
||||
'and also includes building the Linux kernel. If "all" is used '
|
||||
'then the total uncompressed size is around 13 GB.')
|
||||
'then the total uncompressed size is around 13 GB. '
|
||||
'Choices: %s' % ', '.join(download_choices))
|
||||
p.add_argument(
|
||||
'--allow-missing', action='store_true',
|
||||
help='Permit benchmarks to run even if some commands are missing.')
|
||||
p.add_argument(
|
||||
'-f', '--force', action='store_true',
|
||||
help='Overwrite existing files if there is a conflict.')
|
||||
@@ -843,13 +1203,29 @@ def main():
|
||||
'--raw', metavar='PATH',
|
||||
help='Dump raw data (all samples collected) in CSV format to the '
|
||||
'file path provided.')
|
||||
p.add_argument(
|
||||
'--warmup-iter', metavar='INTEGER', type=int, default=1,
|
||||
help='The number of iterations to run each command before '
|
||||
'recording measurements.')
|
||||
p.add_argument(
|
||||
'--bench-iter', metavar='INTEGER', type=int, default=3,
|
||||
help='The number of iterations to run each command while '
|
||||
'recording measurements.')
|
||||
p.add_argument(
|
||||
'bench', metavar='PAT', nargs='?',
|
||||
help='A regex pattern that will only run benchmarks that match.')
|
||||
args = p.parse_args()
|
||||
|
||||
if args.list:
|
||||
benchmarks = collect_benchmarks(
|
||||
args.dir, filter_pat=args.bench,
|
||||
allow_missing_commands=args.allow_missing,
|
||||
warmup_iter=args.warmup_iter, bench_iter=args.bench_iter)
|
||||
for b in benchmarks:
|
||||
print(b.name)
|
||||
sys.exit(0)
|
||||
if args.download is not None and len(args.download) > 0:
|
||||
download(args.dir, args.choices)
|
||||
download(args.dir, args.download)
|
||||
sys.exit(0)
|
||||
|
||||
if not path.isdir(args.dir):
|
||||
@@ -867,7 +1243,10 @@ def main():
|
||||
raw_csv_wtr = csv.DictWriter(raw_handle, fields)
|
||||
raw_csv_wtr.writerow({x: x for x in fields})
|
||||
|
||||
benchmarks = collect_benchmarks(args.dir, filter_pat=args.bench)
|
||||
benchmarks = collect_benchmarks(
|
||||
args.dir, filter_pat=args.bench,
|
||||
allow_missing_commands=args.allow_missing,
|
||||
warmup_iter=args.warmup_iter, bench_iter=args.bench_iter)
|
||||
for i, b in enumerate(benchmarks):
|
||||
result = b.run()
|
||||
fastest_cmd = result.fastest_cmd()
|
||||
@@ -881,6 +1260,12 @@ def main():
|
||||
for cmd in b.commands:
|
||||
name = cmd.name
|
||||
mean, stdev = result.distribution_for(cmd)
|
||||
if mean is None:
|
||||
# If we couldn't get a distribution for this command then
|
||||
# it was skipped.
|
||||
print('{name:{pad}} SKIPPED'.format(
|
||||
name=name, pad=max_name_len + 2))
|
||||
continue
|
||||
line_counts = result.line_counts_for(cmd)
|
||||
show_fast_cmd, show_line_counts = '', ''
|
||||
if fastest_cmd.name == cmd.name:
|
343
benchsuite/raw.csv
Normal file
343
benchsuite/raw.csv
Normal file
@@ -0,0 +1,343 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg,rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24781584739685059,68,
|
||||
linux_alternates,1,3,rg,rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23398137092590332,68,
|
||||
linux_alternates,1,3,rg,rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23497819900512695,68,
|
||||
linux_alternates,1,3,rg-novcs,rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.11090731620788574,68,
|
||||
linux_alternates,1,3,rg-novcs,rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.14237189292907715,68,
|
||||
linux_alternates,1,3,rg-novcs,rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.11315393447875977,68,
|
||||
linux_alternates,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39145565032958984,68,
|
||||
linux_alternates,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39217114448547363,68,
|
||||
linux_alternates,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39917516708374023,68,
|
||||
linux_alternates,1,3,ag,ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4898416996002197,68,
|
||||
linux_alternates,1,3,ag,ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5078432559967041,68,
|
||||
linux_alternates,1,3,ag,ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4942047595977783,68,
|
||||
linux_alternates,1,3,ag-novcs,ag --skip-vcs-ignores -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4839494228363037,68,
|
||||
linux_alternates,1,3,ag-novcs,ag --skip-vcs-ignores -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4806060791015625,68,
|
||||
linux_alternates,1,3,ag-novcs,ag --skip-vcs-ignores -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6986649036407471,68,
|
||||
linux_alternates,1,3,ucg,ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1494297981262207,68,
|
||||
linux_alternates,1,3,ucg,ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.15127253532409668,68,
|
||||
linux_alternates,1,3,ucg,ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.1573657989501953,68,
|
||||
linux_alternates,1,3,git grep,git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.25092005729675293,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep,git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2663850784301758,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep,git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24485993385314941,68,LC_ALL=C
|
||||
linux_alternates_casei,1,3,rg,rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.24762463569641113,160,
|
||||
linux_alternates_casei,1,3,rg,rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.21982502937316895,160,
|
||||
linux_alternates_casei,1,3,rg,rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2219092845916748,160,
|
||||
linux_alternates_casei,1,3,rg-novcs,rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12809348106384277,160,
|
||||
linux_alternates_casei,1,3,rg-novcs,rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12208032608032227,160,
|
||||
linux_alternates_casei,1,3,rg-novcs,rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.12648415565490723,160,
|
||||
linux_alternates_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39945435523986816,160,
|
||||
linux_alternates_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.39914917945861816,160,
|
||||
linux_alternates_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.3931403160095215,160,
|
||||
linux_alternates_casei,1,3,ag,ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.26180100440979,160,
|
||||
linux_alternates_casei,1,3,ag,ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6076450347900391,160,
|
||||
linux_alternates_casei,1,3,ag,ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6092875003814697,160,
|
||||
linux_alternates_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5668354034423828,160,
|
||||
linux_alternates_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5638954639434814,160,
|
||||
linux_alternates_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.6463086605072021,160,
|
||||
linux_alternates_casei,1,3,ucg,ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23877739906311035,160,
|
||||
linux_alternates_casei,1,3,ucg,ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2357316017150879,160,
|
||||
linux_alternates_casei,1,3,ucg,ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.23951983451843262,160,
|
||||
linux_alternates_casei,1,3,git grep,git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.8604335784912109,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep,git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9313437938690186,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep,git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.9674036502838135,160,LC_ALL=C
|
||||
linux_literal,1,3,rg,rg -n PM_RESUME,0.2203836441040039,16,
|
||||
linux_literal,1,3,rg,rg -n PM_RESUME,0.21490192413330078,16,
|
||||
linux_literal,1,3,rg,rg -n PM_RESUME,0.21895813941955566,16,
|
||||
linux_literal,1,3,rg-novcs,rg --no-ignore -n PM_RESUME,0.10370588302612305,16,
|
||||
linux_literal,1,3,rg-novcs,rg --no-ignore -n PM_RESUME,0.12161660194396973,16,
|
||||
linux_literal,1,3,rg-novcs,rg --no-ignore -n PM_RESUME,0.10118246078491211,16,
|
||||
linux_literal,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n PM_RESUME,0.3846700191497803,16,
|
||||
linux_literal,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n PM_RESUME,0.3972609043121338,16,
|
||||
linux_literal,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n PM_RESUME,0.3864939212799072,16,
|
||||
linux_literal,1,3,ag,ag -s PM_RESUME,0.5170495510101318,16,
|
||||
linux_literal,1,3,ag,ag -s PM_RESUME,0.5066406726837158,16,
|
||||
linux_literal,1,3,ag,ag -s PM_RESUME,0.5110535621643066,16,
|
||||
linux_literal,1,3,ag-novcs,ag --skip-vcs-ignores -s PM_RESUME,0.5622231960296631,16,
|
||||
linux_literal,1,3,ag-novcs,ag --skip-vcs-ignores -s PM_RESUME,0.7810573577880859,16,
|
||||
linux_literal,1,3,ag-novcs,ag --skip-vcs-ignores -s PM_RESUME,1.2847375869750977,16,
|
||||
linux_literal,1,3,ucg,ucg --nosmart-case PM_RESUME,0.16497445106506348,16,
|
||||
linux_literal,1,3,ucg,ucg --nosmart-case PM_RESUME,0.16525840759277344,16,
|
||||
linux_literal,1,3,ucg,ucg --nosmart-case PM_RESUME,0.1590101718902588,16,
|
||||
linux_literal,1,3,git grep,git grep -I -n PM_RESUME,0.1928420066833496,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep,git grep -I -n PM_RESUME,0.19345307350158691,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep,git grep -I -n PM_RESUME,0.1954176425933838,16,LC_ALL=C
|
||||
linux_literal,1,3,pt,pt PM_RESUME,0.20350170135498047,16,
|
||||
linux_literal,1,3,pt,pt PM_RESUME,0.17547011375427246,16,
|
||||
linux_literal,1,3,pt,pt PM_RESUME,0.21206402778625488,16,
|
||||
linux_literal,1,3,sift,sift -n --binary-skip --exclude-files .* PM_RESUME,0.14285612106323242,16,
|
||||
linux_literal,1,3,sift,sift -n --binary-skip --exclude-files .* PM_RESUME,0.14221596717834473,16,
|
||||
linux_literal,1,3,sift,sift -n --binary-skip --exclude-files .* PM_RESUME,0.1395282745361328,16,
|
||||
linux_literal_casei,1,3,rg,rg -n -i PM_RESUME,0.32401490211486816,370,
|
||||
linux_literal_casei,1,3,rg,rg -n -i PM_RESUME,0.26114439964294434,370,
|
||||
linux_literal_casei,1,3,rg,rg -n -i PM_RESUME,0.21575093269348145,370,
|
||||
linux_literal_casei,1,3,rg-novcs,rg --no-ignore -n -i PM_RESUME,0.13971185684204102,399,
|
||||
linux_literal_casei,1,3,rg-novcs,rg --no-ignore -n -i PM_RESUME,0.11648797988891602,399,
|
||||
linux_literal_casei,1,3,rg-novcs,rg --no-ignore -n -i PM_RESUME,0.11060571670532227,399,
|
||||
linux_literal_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i PM_RESUME,0.41420912742614746,399,
|
||||
linux_literal_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i PM_RESUME,0.3933844566345215,399,
|
||||
linux_literal_casei,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -i PM_RESUME,0.4015076160430908,399,
|
||||
linux_literal_casei,1,3,ag,ag -i PM_RESUME,0.45723628997802734,370,
|
||||
linux_literal_casei,1,3,ag,ag -i PM_RESUME,0.41663575172424316,370,
|
||||
linux_literal_casei,1,3,ag,ag -i PM_RESUME,0.4088137149810791,370,
|
||||
linux_literal_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i PM_RESUME,0.44587063789367676,399,
|
||||
linux_literal_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i PM_RESUME,0.45557403564453125,399,
|
||||
linux_literal_casei,1,3,ag-novcs,ag --skip-vcs-ignores -i PM_RESUME,0.41840505599975586,399,
|
||||
linux_literal_casei,1,3,ucg,ucg -i PM_RESUME,0.1598954200744629,370,
|
||||
linux_literal_casei,1,3,ucg,ucg -i PM_RESUME,0.15562868118286133,370,
|
||||
linux_literal_casei,1,3,ucg,ucg -i PM_RESUME,0.15644288063049316,370,
|
||||
linux_literal_casei,1,3,git grep,git grep -I -n -i PM_RESUME,0.1857764720916748,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep,git grep -I -n -i PM_RESUME,0.17730069160461426,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep,git grep -I -n -i PM_RESUME,0.18560075759887695,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,sift,sift -n --binary-skip --exclude-files .* -i PM_RESUME,0.20816397666931152,399,
|
||||
linux_literal_casei,1,3,sift,sift -n --binary-skip --exclude-files .* -i PM_RESUME,0.1995244026184082,399,
|
||||
linux_literal_casei,1,3,sift,sift -n --binary-skip --exclude-files .* -i PM_RESUME,0.2000412940979004,399,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.21781229972839355,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.2195730209350586,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.259692907333374,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.39571118354797363,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.48991870880126953,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,0.49497532844543457,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.166459321975708,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.1644885540008545,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.16440844535827637,16,
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.1860334873199463,16,LC_ALL=C
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.16703486442565918,16,LC_ALL=C
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.20740580558776855,16,LC_ALL=C
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15500974655151367,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15694642066955566,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.15679144859313965,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11694097518920898,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11726593971252441,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.11739015579223633,16,
|
||||
linux_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3873450756072998,490,
|
||||
linux_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.38909482955932617,490,
|
||||
linux_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4019286632537842,490,
|
||||
linux_no_literal,1,3,rg-whitelist,rg -tall --no-ignore -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32698678970336914,419,
|
||||
linux_no_literal,1,3,rg-whitelist,rg -tall --no-ignore -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3220486640930176,419,
|
||||
linux_no_literal,1,3,rg-whitelist,rg -tall --no-ignore -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32451391220092773,419,
|
||||
linux_no_literal,1,3,rg (no Unicode),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.2920851707458496,490,
|
||||
linux_no_literal,1,3,rg (no Unicode),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3335237503051758,490,
|
||||
linux_no_literal,1,3,rg (no Unicode),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.28688979148864746,490,
|
||||
linux_no_literal,1,3,rg-whitelist (no Unicode),rg -tall --no-ignore -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.222395658493042,419,
|
||||
linux_no_literal,1,3,rg-whitelist (no Unicode),rg -tall --no-ignore -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.22271037101745605,419,
|
||||
linux_no_literal,1,3,rg-whitelist (no Unicode),rg -tall --no-ignore -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.23732328414916992,419,
|
||||
linux_no_literal,1,3,ag (no Unicode),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7565908432006836,766,
|
||||
linux_no_literal,1,3,ag (no Unicode),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.9270203113555908,766,
|
||||
linux_no_literal,1,3,ag (no Unicode),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7432494163513184,766,
|
||||
linux_no_literal,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.6899797916412354,767,
|
||||
linux_no_literal,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7057938575744629,767,
|
||||
linux_no_literal,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.7126791477203369,767,
|
||||
linux_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.44383835792541504,416,
|
||||
linux_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4448375701904297,416,
|
||||
linux_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4412264823913574,416,
|
||||
linux_no_literal,1,3,git grep,git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.985018730163574,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep,git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.671714782714844,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep,git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},9.0708589553833,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (no Unicode),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.9452569484710693,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (no Unicode),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.3153109550476074,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (no Unicode),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.876504898071289,490,LC_ALL=C
|
||||
linux_no_literal,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.800794124603271,491,
|
||||
linux_no_literal,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.91090989112854,491,
|
||||
linux_no_literal,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},8.970277547836304,491,
|
||||
linux_re_literal_suffix,1,3,rg,rg -n [A-Z]+_RESUME,0.21518707275390625,1652,
|
||||
linux_re_literal_suffix,1,3,rg,rg -n [A-Z]+_RESUME,0.2159252166748047,1652,
|
||||
linux_re_literal_suffix,1,3,rg,rg -n [A-Z]+_RESUME,0.2178945541381836,1652,
|
||||
linux_re_literal_suffix,1,3,rg-novcs,rg --no-ignore -n [A-Z]+_RESUME,0.10395693778991699,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs,rg --no-ignore -n [A-Z]+_RESUME,0.101318359375,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs,rg --no-ignore -n [A-Z]+_RESUME,0.09963226318359375,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n [A-Z]+_RESUME,0.40993452072143555,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n [A-Z]+_RESUME,0.4102144241333008,1653,
|
||||
linux_re_literal_suffix,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n [A-Z]+_RESUME,0.3837263584136963,1653,
|
||||
linux_re_literal_suffix,1,3,ag,ag -s [A-Z]+_RESUME,1.7373137474060059,1652,
|
||||
linux_re_literal_suffix,1,3,ag,ag -s [A-Z]+_RESUME,1.7011380195617676,1652,
|
||||
linux_re_literal_suffix,1,3,ag,ag -s [A-Z]+_RESUME,0.7572276592254639,1652,
|
||||
linux_re_literal_suffix,1,3,ag-novcs,ag --skip-vcs-ignores -s [A-Z]+_RESUME,0.5061535835266113,1653,
|
||||
linux_re_literal_suffix,1,3,ag-novcs,ag --skip-vcs-ignores -s [A-Z]+_RESUME,0.5377681255340576,1653,
|
||||
linux_re_literal_suffix,1,3,ag-novcs,ag --skip-vcs-ignores -s [A-Z]+_RESUME,0.5237703323364258,1653,
|
||||
linux_re_literal_suffix,1,3,ucg,ucg --nosmart-case [A-Z]+_RESUME,0.13993382453918457,1630,
|
||||
linux_re_literal_suffix,1,3,ucg,ucg --nosmart-case [A-Z]+_RESUME,0.14264798164367676,1630,
|
||||
linux_re_literal_suffix,1,3,ucg,ucg --nosmart-case [A-Z]+_RESUME,0.1370248794555664,1630,
|
||||
linux_re_literal_suffix,1,3,git grep,git grep -E -I -n [A-Z]+_RESUME,0.5916049480438232,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep,git grep -E -I -n [A-Z]+_RESUME,0.5460302829742432,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep,git grep -E -I -n [A-Z]+_RESUME,0.5453126430511475,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,sift,sift -n --binary-skip --exclude-files .* [A-Z]+_RESUME,4.272618055343628,1653,
|
||||
linux_re_literal_suffix,1,3,sift,sift -n --binary-skip --exclude-files .* [A-Z]+_RESUME,3.953784704208374,1653,
|
||||
linux_re_literal_suffix,1,3,sift,sift -n --binary-skip --exclude-files .* [A-Z]+_RESUME,4.050055742263794,1653,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2921295166015625,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.2845008373260498,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.295884370803833,23,
|
||||
linux_unicode_greek,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.8051228523254395,23,
|
||||
linux_unicode_greek,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.824496269226074,23,
|
||||
linux_unicode_greek,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.8370847702026367,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.2810385227203369,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.3430476188659668,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.34683680534362793,103,
|
||||
linux_unicode_greek_casei,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.8701119422912598,23,
|
||||
linux_unicode_greek_casei,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.9307808876037598,23,
|
||||
linux_unicode_greek_casei,1,3,sift,sift -n --binary-skip --exclude-files .* --exclude-files *.pdf \p{Greek},2.9754345417022705,23,
|
||||
linux_unicode_word,1,3,rg,rg -n \wAh,0.21484971046447754,186,
|
||||
linux_unicode_word,1,3,rg,rg -n \wAh,0.2730236053466797,186,
|
||||
linux_unicode_word,1,3,rg,rg -n \wAh,0.21688318252563477,186,
|
||||
linux_unicode_word,1,3,rg (no Unicode),rg -n (?-u)\wAh,0.23591041564941406,174,
|
||||
linux_unicode_word,1,3,rg (no Unicode),rg -n (?-u)\wAh,0.23375535011291504,174,
|
||||
linux_unicode_word,1,3,rg (no Unicode),rg -n (?-u)\wAh,0.23137831687927246,174,
|
||||
linux_unicode_word,1,3,rg-novcs,rg --no-ignore -n \wAh,0.11421418190002441,186,
|
||||
linux_unicode_word,1,3,rg-novcs,rg --no-ignore -n \wAh,0.11203289031982422,186,
|
||||
linux_unicode_word,1,3,rg-novcs,rg --no-ignore -n \wAh,0.10834765434265137,186,
|
||||
linux_unicode_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n \wAh,0.39345431327819824,186,
|
||||
linux_unicode_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n \wAh,0.40348386764526367,186,
|
||||
linux_unicode_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n \wAh,0.40167927742004395,186,
|
||||
linux_unicode_word,1,3,ag (no Unicode),ag -s \wAh,0.9391078948974609,174,
|
||||
linux_unicode_word,1,3,ag (no Unicode),ag -s \wAh,0.9322304725646973,174,
|
||||
linux_unicode_word,1,3,ag (no Unicode),ag -s \wAh,0.9393062591552734,174,
|
||||
linux_unicode_word,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \wAh,0.9509954452514648,174,
|
||||
linux_unicode_word,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \wAh,0.9229059219360352,174,
|
||||
linux_unicode_word,1,3,ag-novcs (no Unicode),ag --skip-vcs-ignores -s \wAh,0.8915724754333496,174,
|
||||
linux_unicode_word,1,3,ucg (no Unicode),ucg --nosmart-case \wAh,0.1719198226928711,168,
|
||||
linux_unicode_word,1,3,ucg (no Unicode),ucg --nosmart-case \wAh,0.18027615547180176,168,
|
||||
linux_unicode_word,1,3,ucg (no Unicode),ucg --nosmart-case \wAh,0.17251205444335938,168,
|
||||
linux_unicode_word,1,3,git grep,git grep -E -I -n \wAh,4.980919122695923,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep,git grep -E -I -n \wAh,4.995086193084717,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep,git grep -E -I -n \wAh,4.941043376922607,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (no Unicode),git grep -E -I -n \wAh,1.5811383724212646,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (no Unicode),git grep -E -I -n \wAh,1.5947043895721436,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (no Unicode),git grep -E -I -n \wAh,1.522637128829956,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \wAh,4.356529951095581,174,
|
||||
linux_unicode_word,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \wAh,4.129682540893555,174,
|
||||
linux_unicode_word,1,3,sift (no Unicode),sift -n --binary-skip --exclude-files .* \wAh,4.098994731903076,174,
|
||||
linux_word,1,3,rg,rg -n -w PM_RESUME,0.21953463554382324,6,
|
||||
linux_word,1,3,rg,rg -n -w PM_RESUME,0.2401576042175293,6,
|
||||
linux_word,1,3,rg,rg -n -w PM_RESUME,0.21302008628845215,6,
|
||||
linux_word,1,3,rg-novcs,rg --no-ignore -n -w PM_RESUME,0.14854192733764648,6,
|
||||
linux_word,1,3,rg-novcs,rg --no-ignore -n -w PM_RESUME,0.09938955307006836,6,
|
||||
linux_word,1,3,rg-novcs,rg --no-ignore -n -w PM_RESUME,0.1005239486694336,6,
|
||||
linux_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -w PM_RESUME,0.3981668949127197,6,
|
||||
linux_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -w PM_RESUME,0.3999497890472412,6,
|
||||
linux_word,1,3,rg-novcs-mmap,rg --mmap --no-ignore -n -w PM_RESUME,0.38619542121887207,6,
|
||||
linux_word,1,3,ag,ag -s -w PM_RESUME,0.6837906837463379,6,
|
||||
linux_word,1,3,ag,ag -s -w PM_RESUME,0.6158981323242188,6,
|
||||
linux_word,1,3,ag,ag -s -w PM_RESUME,0.41248440742492676,6,
|
||||
linux_word,1,3,ag-novcs,ag --skip-vcs-ignores -s -w PM_RESUME,0.42545604705810547,6,
|
||||
linux_word,1,3,ag-novcs,ag --skip-vcs-ignores -s -w PM_RESUME,0.4142575263977051,6,
|
||||
linux_word,1,3,ag-novcs,ag --skip-vcs-ignores -s -w PM_RESUME,0.4717123508453369,6,
|
||||
linux_word,1,3,ucg,ucg --nosmart-case -w PM_RESUME,0.1639394760131836,6,
|
||||
linux_word,1,3,ucg,ucg --nosmart-case -w PM_RESUME,0.16333961486816406,6,
|
||||
linux_word,1,3,ucg,ucg --nosmart-case -w PM_RESUME,0.16097497940063477,6,
|
||||
linux_word,1,3,git grep,git grep -E -I -n -w PM_RESUME,0.17300987243652344,6,LC_ALL=C
|
||||
linux_word,1,3,git grep,git grep -E -I -n -w PM_RESUME,0.171494722366333,6,LC_ALL=C
|
||||
linux_word,1,3,git grep,git grep -E -I -n -w PM_RESUME,0.19692277908325195,6,LC_ALL=C
|
||||
linux_word,1,3,sift,sift -n --binary-skip --exclude-files .* -w PM_RESUME,3.190856695175171,6,
|
||||
linux_word,1,3,sift,sift -n --binary-skip --exclude-files .* -w PM_RESUME,3.1970269680023193,6,
|
||||
linux_word,1,3,sift,sift -n --binary-skip --exclude-files .* -w PM_RESUME,3.094048500061035,6,
|
||||
subtitles_en_literal,1,3,rg,rg -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.41990160942077637,629,
|
||||
subtitles_en_literal,1,3,rg,rg -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5151379108428955,629,
|
||||
subtitles_en_literal,1,3,rg,rg -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5245285034179688,629,
|
||||
subtitles_en_literal,1,3,rg (no line numbers),rg Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2494678497314453,629,
|
||||
subtitles_en_literal,1,3,rg (no line numbers),rg Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2570071220397949,629,
|
||||
subtitles_en_literal,1,3,rg (no line numbers),rg Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.20493078231811523,629,
|
||||
subtitles_en_literal,1,3,ag,ag -s Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.0035574436187744,629,
|
||||
subtitles_en_literal,1,3,ag,ag -s Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,2.004251003265381,629,
|
||||
subtitles_en_literal,1,3,ag,ag -s Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.998549222946167,629,
|
||||
subtitles_en_literal,1,3,ucg,ucg --nosmart-case Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.750638484954834,629,
|
||||
subtitles_en_literal,1,3,ucg,ucg --nosmart-case Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7518937587738037,629,
|
||||
subtitles_en_literal,1,3,ucg,ucg --nosmart-case Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.6610665321350098,629,
|
||||
subtitles_en_literal,1,3,grep,grep -an Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.9856901168823242,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -an Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0250558853149414,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -an Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.0195670127868652,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (no line numbers),grep -a Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5834128856658936,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (no line numbers),grep -a Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5891468524932861,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (no line numbers),grep -a Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5075380802154541,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,pt,pt Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6499581336975098,629,
|
||||
subtitles_en_literal,1,3,pt,pt Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.667529821395874,629,
|
||||
subtitles_en_literal,1,3,pt,pt Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6895508766174316,629,
|
||||
subtitles_en_literal,1,3,pt (no line numbers),pt -N Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.4941000938415527,629,
|
||||
subtitles_en_literal,1,3,pt (no line numbers),pt -N Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.670578956604004,629,
|
||||
subtitles_en_literal,1,3,pt (no line numbers),pt -N Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,1.6264257431030273,629,
|
||||
subtitles_en_literal,1,3,sift,sift -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7577519416809082,629,
|
||||
subtitles_en_literal,1,3,sift,sift -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.7018873691558838,629,
|
||||
subtitles_en_literal,1,3,sift,sift -n Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.5913088321685791,629,
|
||||
subtitles_en_literal,1,3,sift (no line numbers),sift Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2632462978363037,629,
|
||||
subtitles_en_literal,1,3,sift (no line numbers),sift Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.2749521732330322,629,
|
||||
subtitles_en_literal,1,3,sift (no line numbers),sift Sherlock Holmes /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.sample.en,0.27170491218566895,629,
|
||||
subtitles_ru_alternate,1,3,rg,rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6460118293762207,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5819060802459717,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.7640905380249023,691,
|
||||
subtitles_ru_alternate,1,3,rg (no line numbers),rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.2313611507415771,691,
|
||||
subtitles_ru_alternate,1,3,rg (no line numbers),rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3044109344482422,691,
|
||||
subtitles_ru_alternate,1,3,rg (no line numbers),rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3338491916656494,691,
|
||||
subtitles_ru_alternate,1,3,ucg,ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.3752894401550293,691,
|
||||
subtitles_ru_alternate,1,3,ucg,ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.370604991912842,691,
|
||||
subtitles_ru_alternate,1,3,ucg,ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.399735689163208,691,
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.716331243515015,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.910337448120117,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.955447435379028,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (no line numbers),grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.488590240478516,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (no line numbers),grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.247926950454712,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (no line numbers),grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.541552305221558,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.170270681381226,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.186170816421509,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.001753807067871,735,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.2377853393554688,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.361377477645874,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.4316565990448,691,
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.9808149337768555,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.773010015487671,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.952658414840698,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.799196481704712,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.990447282791138,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.916130781173706,691,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,rg,rg -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.824413537979126,583,
|
||||
subtitles_ru_literal,1,3,rg,rg -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8357686996459961,583,
|
||||
subtitles_ru_literal,1,3,rg,rg -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8958892822265625,583,
|
||||
subtitles_ru_literal,1,3,rg (no line numbers),rg Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.2959728240966797,583,
|
||||
subtitles_ru_literal,1,3,rg (no line numbers),rg Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3027801513671875,583,
|
||||
subtitles_ru_literal,1,3,rg (no line numbers),rg Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.3133840560913086,583,
|
||||
subtitles_ru_literal,1,3,ag,ag -s Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.8583695888519287,583,
|
||||
subtitles_ru_literal,1,3,ag,ag -s Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.0803942680358887,583,
|
||||
subtitles_ru_literal,1,3,ag,ag -s Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.092284679412842,583,
|
||||
subtitles_ru_literal,1,3,ucg,ucg --nosmart-case Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5811631679534912,583,
|
||||
subtitles_ru_literal,1,3,ucg,ucg --nosmart-case Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5879406929016113,583,
|
||||
subtitles_ru_literal,1,3,ucg,ucg --nosmart-case Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5010735988616943,583,
|
||||
subtitles_ru_literal,1,3,grep,grep -an Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3335914611816406,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -an Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3385870456695557,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -an Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3321411609649658,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (no line numbers),grep -a Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8784911632537842,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (no line numbers),grep -a Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8721048831939697,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (no line numbers),grep -a Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,0.8763093948364258,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,pt,pt Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.429335355758667,583,
|
||||
subtitles_ru_literal,1,3,pt,pt Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,4.938883543014526,583,
|
||||
subtitles_ru_literal,1,3,pt,pt Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.5893049240112305,583,
|
||||
subtitles_ru_literal,1,3,pt (no line numbers),pt -N Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.522632598876953,583,
|
||||
subtitles_ru_literal,1,3,pt (no line numbers),pt -N Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.237533330917358,583,
|
||||
subtitles_ru_literal,1,3,pt (no line numbers),pt -N Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,5.215710401535034,583,
|
||||
subtitles_ru_literal,1,3,sift,sift -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.944578170776367,583,
|
||||
subtitles_ru_literal,1,3,sift,sift -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.835101127624512,583,
|
||||
subtitles_ru_literal,1,3,sift,sift -n Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.847816228866577,583,
|
||||
subtitles_ru_literal,1,3,sift (no line numbers),sift Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.25161075592041,583,
|
||||
subtitles_ru_literal,1,3,sift (no line numbers),sift Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.299700736999512,583,
|
||||
subtitles_ru_literal,1,3,sift (no line numbers),sift Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.38068151473999,583,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -n -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.6576766967773438,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -n -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.4723634719848633,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -n -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.775054931640625,604,
|
||||
subtitles_ru_literal_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5934054851531982,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.597702980041504,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (not Unicode),ucg -i Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.5229814052581787,583,
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.458112478256226,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.91841197013855,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,6.809293508529663,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.3416473865509033,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.1377508640289307,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (not Unicode),grep -E -ani Шерлок Холмс /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.146819829940796,583,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.7402286529541016,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.872703790664673,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.8877029418945312,41,
|
||||
subtitles_ru_no_literal,1,3,rg (no line numbers),rg \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.414641857147217,41,
|
||||
subtitles_ru_no_literal,1,3,rg (no line numbers),rg \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.4537253379821777,41,
|
||||
subtitles_ru_no_literal,1,3,rg (no line numbers),rg \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,3.460618019104004,41,
|
||||
subtitles_ru_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.290541648864746,,
|
||||
subtitles_ru_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.311371088027954,,
|
||||
subtitles_ru_no_literal,1,3,ucg (no Unicode),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.1349129676818848,,
|
||||
subtitles_ru_no_literal,1,3,grep (no Unicode),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8941442966461182,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,grep (no Unicode),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,1.8850946426391602,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,grep (no Unicode),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /home/andrew/tmp/benchsuite/subtitles/OpenSubtitles2016.raw.ru,2.074228525161743,,LC_ALL=C
|
|
93
benchsuite/runs/2016-09-17-ubuntu1604-ec2/README.SETUP
Normal file
93
benchsuite/runs/2016-09-17-ubuntu1604-ec2/README.SETUP
Normal file
@@ -0,0 +1,93 @@
|
||||
Ubuntu 16.04 HVM AMI
|
||||
c3.2xlarge, Xeon E5-2680, 2.8 GHz, 8 CPUs, 16 GB memory, 80 GB SSD
|
||||
|
||||
# Generic system setup
|
||||
|
||||
mkfs.ext4 /dev/xvdb
|
||||
sudo mount /dev/xvdb /mnt
|
||||
sudo chown ubuntu /mnt
|
||||
sudo apt-get update
|
||||
sudo apt-get install \ # for building Linux kernel
|
||||
make gcc bc
|
||||
sudo apt-get install \ # for the silver searcher
|
||||
automake pkg-config zlib1g-dev liblzma-dev libpcre3 libpcre3-dev
|
||||
sudo apt-get install \ # for Universal Code Grep
|
||||
libtool libpcre2-8-0 libpcre2-dev
|
||||
sudo apt-get install \ # for sift and the platinum searcher
|
||||
go
|
||||
|
||||
# Get benchmark corpora
|
||||
|
||||
cd /mnt
|
||||
mkdir /mnt/bench
|
||||
git clone git://github.com/BurntSushi/ripgrep
|
||||
cd ripgrep/benchsuite
|
||||
./benchsuite --dir /mnt/bench/ --download all # takes around 15 minutes
|
||||
|
||||
# Install search tools
|
||||
mkdir /mnt/bin/
|
||||
|
||||
## ripgrep
|
||||
|
||||
cd /mnt
|
||||
mkdir ripgrep-bin
|
||||
cd ripgrep-bin
|
||||
curl -LO 'https://github.com/BurntSushi/ripgrep/releases/download/0.1.2/ripgrep-0.1.2-x86_64-unknown-linux-musl.tar.gz'
|
||||
cp ripgrep-0.1.2-x86_64-unknown-linux-musl/rg /mnt/bin/
|
||||
|
||||
## The Silver Searcher
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/ggreer/the_silver_searcher
|
||||
cd the_silver_searcher
|
||||
git checkout cda635
|
||||
./build.sh
|
||||
cp ag /mnt/bin/
|
||||
|
||||
## Universal Code Grep
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/gvansickle/ucg
|
||||
cd ucg
|
||||
git checkout 487bfb
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ucg /mnt/bin/
|
||||
|
||||
## The Platinum Searcher
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/monochromegane/the_platinum_searcher
|
||||
cd /mnt/go/src/github.com/monochromegane/the_platinum_searcher
|
||||
git checkout 509368
|
||||
go install github.com/monochromegane/the_platinum_searcher/cmd/...
|
||||
cp /mnt/go/bin/pt /mnt/bin/
|
||||
|
||||
## Sift
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/svent/sift
|
||||
cd /mnt/go/src/github.com/svent/sift
|
||||
git checkout 2d175c
|
||||
go install
|
||||
cp /mnt/go/bin/sift /mnt/bin/
|
||||
|
||||
## 'git grep' and GNU grep
|
||||
|
||||
They are part of the standard Ubuntu install, and are pretty recent (as of
|
||||
September 2016).
|
||||
|
||||
$ git --version
|
||||
git version 2.7.4
|
||||
$ grep --version
|
||||
grep (GNU grep) 2.25
|
||||
|
||||
|
||||
# Running benchmarks
|
||||
|
||||
export PATH="/mnt/bin:$PATH"
|
||||
cd /mnt/ripgrep/benchsuite
|
||||
./benchsuite --dir /mnt/bench/ --raw /mnt/bench/raw.csv \
|
||||
| tee /mnt/bench/summary
|
||||
# The above took around 30 minutes to run to completion.
|
457
benchsuite/runs/2016-09-17-ubuntu1604-ec2/raw.csv
Normal file
457
benchsuite/runs/2016-09-17-ubuntu1604-ec2/raw.csv
Normal file
@@ -0,0 +1,457 @@
|
||||
benchmark,warmup_iter,iter,name,command,duration,lines,env
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.30042552947998047,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.3699159622192383,68,
|
||||
linux_alternates,1,3,rg (ignore),rg -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.2950403690338135,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.7572166919708252,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.7568728923797607,68,
|
||||
linux_alternates,1,3,ag (ignore),ag -s ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.7468714714050293,68,
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5062770843505859,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.49932026863098145,68,LC_ALL=C
|
||||
linux_alternates,1,3,git grep (ignore),git grep -E -I -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5008277893066406,68,LC_ALL=C
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.19775605201721191,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.19699668884277344,68,
|
||||
linux_alternates,1,3,rg (whitelist),rg --no-ignore -n ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.19636178016662598,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.21344256401062012,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.21743154525756836,68,
|
||||
linux_alternates,1,3,ucg (whitelist),ucg --nosmart-case ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.22065043449401855,68,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.31632304191589355,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.3168807029724121,160,
|
||||
linux_alternates_casei,1,3,rg (ignore),rg -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.4834277629852295,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.9558978080749512,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.9736671447753906,160,
|
||||
linux_alternates_casei,1,3,ag (ignore),ag -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,1.9648356437683105,160,
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,2.0229439735412598,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,2.0214922428131104,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,git grep (ignore),git grep -E -I -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,2.022616147994995,160,LC_ALL=C
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.22146987915039062,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.22275280952453613,160,
|
||||
linux_alternates_casei,1,3,rg (whitelist),rg --no-ignore -n -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.22226715087890625,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5290391445159912,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5196049213409424,160,
|
||||
linux_alternates_casei,1,3,ucg (whitelist),ucg -i ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,0.5219125747680664,160,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.2871882915496826,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.38920140266418457,16,
|
||||
linux_literal,1,3,rg (ignore),rg -n PM_RESUME,0.3668382167816162,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,1.6073203086853027,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,1.6012177467346191,16,
|
||||
linux_literal,1,3,rg (ignore) (mmap),rg -n --mmap PM_RESUME,1.5818352699279785,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,1.592775583267212,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,1.5901448726654053,16,
|
||||
linux_literal,1,3,ag (ignore) (mmap),ag -s PM_RESUME,1.586061716079712,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.45094990730285645,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.47065186500549316,16,
|
||||
linux_literal,1,3,pt (ignore),pt PM_RESUME,0.4422800540924072,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.6293809413909912,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.6314799785614014,16,
|
||||
linux_literal,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git PM_RESUME,0.6289358139038086,16,
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.347550630569458,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.345928430557251,16,LC_ALL=C
|
||||
linux_literal,1,3,git grep (ignore),git grep -I -n PM_RESUME,0.33939385414123535,16,LC_ALL=C
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.20830345153808594,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.34220385551452637,16,
|
||||
linux_literal,1,3,rg (whitelist),rg -n --no-ignore -tall PM_RESUME,0.2077772617340088,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.21996808052062988,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.22822093963623047,16,
|
||||
linux_literal,1,3,ucg (whitelist),ucg --nosmart-case PM_RESUME,0.21923017501831055,16,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.2988588809967041,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.5339267253875732,370,
|
||||
linux_literal_casei,1,3,rg (ignore),rg -n -i PM_RESUME,0.43750762939453125,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,1.603757381439209,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,1.618077278137207,370,
|
||||
linux_literal_casei,1,3,rg (ignore) (mmap),rg -n -i --mmap PM_RESUME,1.6234121322631836,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,1.621368646621704,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,1.5698626041412354,370,
|
||||
linux_literal_casei,1,3,ag (ignore) (mmap),ag -i PM_RESUME,1.6105949878692627,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.8005843162536621,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.8044955730438232,370,
|
||||
linux_literal_casei,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git PM_RESUME,0.806922197341919,370,
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.34161829948425293,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.3455958366394043,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,git grep (ignore),git grep -I -n -i PM_RESUME,0.3493361473083496,370,LC_ALL=C
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.2149522304534912,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.21602368354797363,370,
|
||||
linux_literal_casei,1,3,rg (whitelist),rg -n -i --no-ignore -tall PM_RESUME,0.27021098136901855,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.22747421264648438,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.22050881385803223,370,
|
||||
linux_literal_casei,1,3,ucg (whitelist),ucg -i PM_RESUME,0.21217584609985352,370,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.27482175827026367,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.2796294689178467,16,
|
||||
linux_literal_default,1,3,rg,rg PM_RESUME,0.27638936042785645,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,1.598384141921997,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,1.5849597454071045,16,
|
||||
linux_literal_default,1,3,ag,ag PM_RESUME,1.6000149250030518,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.2263963222503662,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.21367835998535156,16,
|
||||
linux_literal_default,1,3,ucg,ucg PM_RESUME,0.21764111518859863,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.42263340950012207,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.467041015625,16,
|
||||
linux_literal_default,1,3,pt,pt PM_RESUME,0.42820048332214355,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.33421826362609863,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.35932135581970215,16,
|
||||
linux_literal_default,1,3,sift,sift PM_RESUME,0.3372631072998047,16,
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.348984956741333,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.34420299530029297,16,LC_ALL=en_US.UTF-8
|
||||
linux_literal_default,1,3,git grep,git grep PM_RESUME,0.33880615234375,16,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.5833027362823486,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.5783836841583252,490,
|
||||
linux_no_literal,1,3,rg (ignore),rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.5806806087493896,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4163496494293213,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.4040029048919678,490,
|
||||
linux_no_literal,1,3,rg (ignore) (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.40265560150146484,490,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.3176910877227783,766,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.3504347801208496,766,
|
||||
linux_no_literal,1,3,ag (ignore) (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},2.317542552947998,766,
|
||||
linux_no_literal,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},25.821982383728027,491,
|
||||
linux_no_literal,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},25.82067561149597,491,
|
||||
linux_no_literal,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},25.626302242279053,491,
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},26.349210023880005,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},26.34226369857788,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},26.340656995773315,490,LC_ALL=en_US.UTF-8
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},4.14680290222168,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},4.153340578079224,490,LC_ALL=C
|
||||
linux_no_literal,1,3,git grep (ignore) (ASCII),git grep -E -I -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},4.154819011688232,490,LC_ALL=C
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.49768829345703125,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.5121400356292725,419,
|
||||
linux_no_literal,1,3,rg (whitelist),rg -n --no-ignore -tall \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.49718427658081055,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.38550543785095215,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.32651591300964355,419,
|
||||
linux_no_literal,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},0.3246915340423584,419,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.128183126449585,416,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.1255216598510742,416,
|
||||
linux_no_literal,1,3,ucg (whitelist) (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5},1.1268525123596191,416,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.36306214332580566,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.45077037811279297,1652,
|
||||
linux_re_literal_suffix,1,3,rg (ignore),rg -n [A-Z]+_RESUME,0.3804624080657959,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,1.8995850086212158,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,1.8897662162780762,1652,
|
||||
linux_re_literal_suffix,1,3,ag (ignore),ag -s [A-Z]+_RESUME,1.878380537033081,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,10.48949646949768,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,10.289165735244751,1652,
|
||||
linux_re_literal_suffix,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git [A-Z]+_RESUME,10.000468254089355,1652,
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,1.1080453395843506,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,1.10821533203125,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,git grep (ignore),git grep -E -I -n [A-Z]+_RESUME,1.105595588684082,1652,LC_ALL=C
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.2073357105255127,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.20552492141723633,1630,
|
||||
linux_re_literal_suffix,1,3,rg (whitelist),rg -n --no-ignore -tall [A-Z]+_RESUME,0.2061319351196289,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.3013310432434082,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.3005218505859375,1630,
|
||||
linux_re_literal_suffix,1,3,ucg (whitelist),ucg --nosmart-case [A-Z]+_RESUME,0.29984378814697266,1630,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.4162716865539551,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.47885966300964355,23,
|
||||
linux_unicode_greek,1,3,rg,rg -n \p{Greek},0.5135962963104248,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},7.570494651794434,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},7.790151596069336,23,
|
||||
linux_unicode_greek,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n --git \p{Greek},7.783358812332153,23,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.4370443820953369,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.40680766105651855,103,
|
||||
linux_unicode_greek_casei,1,3,rg,rg -n -i \p{Greek},0.4011569023132324,103,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.002422809600830078,,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.002414226531982422,,
|
||||
linux_unicode_greek_casei,1,3,sift,sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -i --git \p{Greek},0.002293109893798828,,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.44771265983581543,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.3006107807159424,186,
|
||||
linux_unicode_word,1,3,rg (ignore),rg -n \wAh,0.3026111125946045,186,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.43827080726623535,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.2931697368621826,174,
|
||||
linux_unicode_word,1,3,rg (ignore) (ASCII),rg -n (?-u)\wAh,0.33072638511657715,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,1.7645132541656494,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,1.7730333805084229,174,
|
||||
linux_unicode_word,1,3,ag (ignore) (ASCII),ag -s \wAh,1.773383378982544,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \wAh,10.872124671936035,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \wAh,11.147738456726074,174,
|
||||
linux_unicode_word,1,3,sift (ignore) (ASCII),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n \wAh,11.029243469238281,174,
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,13.047154664993286,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,13.025037288665771,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore),git grep -E -I -n \wAh,13.081012487411499,186,LC_ALL=en_US.UTF-8
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,2.98722767829895,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,2.987990379333496,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,git grep (ignore) (ASCII),git grep -E -I -n \wAh,2.988698959350586,174,LC_ALL=C
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.21961355209350586,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.2884254455566406,180,
|
||||
linux_unicode_word,1,3,rg (whitelist),rg -n --no-ignore -tall \wAh,0.21905040740966797,180,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.23966765403747559,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.21801042556762695,168,
|
||||
linux_unicode_word,1,3,rg (whitelist) (ASCII),rg -n --no-ignore -tall (?-u)\wAh,0.21909880638122559,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.2259504795074463,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.22269177436828613,168,
|
||||
linux_unicode_word,1,3,ucg (ASCII),ucg --nosmart-case \wAh,0.2259974479675293,168,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.34968090057373047,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.28850769996643066,6,
|
||||
linux_word,1,3,rg (ignore),rg -n -w PM_RESUME,0.34809160232543945,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,1.6134660243988037,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,1.59847092628479,6,
|
||||
linux_word,1,3,ag (ignore),ag -s -w PM_RESUME,1.581369161605835,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,7.644887208938599,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,7.8782219886779785,6,
|
||||
linux_word,1,3,sift (ignore),sift --binary-skip --exclude-files .* --exclude-files *.pdf -n -w --git PM_RESUME,7.754150152206421,6,
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.34302353858947754,6,LC_ALL=C
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.33672142028808594,6,LC_ALL=C
|
||||
linux_word,1,3,git grep (ignore),git grep -E -I -n -w PM_RESUME,0.35193610191345215,6,LC_ALL=C
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.33329272270202637,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.25751829147338867,6,
|
||||
linux_word,1,3,rg (whitelist),rg -n -w --no-ignore -tall PM_RESUME,0.21761608123779297,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.22014284133911133,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.22314929962158203,6,
|
||||
linux_word,1,3,ucg (whitelist),ucg --nosmart-case -w PM_RESUME,0.2202434539794922,6,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.622809886932373,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6181182861328125,848,
|
||||
subtitles_en_alternate,1,3,rg (lines),rg -n Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6205663681030273,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.7565691471099854,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.7561769485473633,848,
|
||||
subtitles_en_alternate,1,3,ag (lines),ag -s Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.7559969425201416,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.4493463039398193,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.44877028465271,848,
|
||||
subtitles_en_alternate,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.4433801174163818,848,
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4114174842834473,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.411625862121582,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep (lines),grep -E -an Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.408623456954956,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2900726795196533,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2905848026275635,848,
|
||||
subtitles_en_alternate,1,3,rg,rg Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2903940677642822,848,
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.9546515941619873,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.955279588699341,848,LC_ALL=C
|
||||
subtitles_en_alternate,1,3,grep,grep -E -a Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.954089403152466,848,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.169135332107544,862,
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.174601078033447,862,
|
||||
subtitles_en_alternate_casei,1,3,ag (ASCII),ag -s -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.1684675216674805,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4171736240386963,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4158167839050293,862,
|
||||
subtitles_en_alternate_casei,1,3,ucg (ASCII),ucg -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4186513423919678,862,
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.531639575958252,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.526550054550171,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,grep (ASCII),grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.528509140014648,862,LC_ALL=C
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.722398281097412,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7225935459136963,862,
|
||||
subtitles_en_alternate_casei,1,3,rg,rg -n -i Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7222185134887695,862,
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.12151837348938,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.119963884353638,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_alternate_casei,1,3,grep,grep -E -ani Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,5.121079683303833,862,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2684764862060547,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.26811957359313965,629,
|
||||
subtitles_en_literal,1,3,rg,rg Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.2684173583984375,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.435128688812256,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4362881183624268,629,
|
||||
subtitles_en_literal,1,3,pt,pt -N Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4399220943450928,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.32662391662597656,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.3277275562286377,629,
|
||||
subtitles_en_literal,1,3,sift,sift Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.32798290252685547,629,
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.520500659942627,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5191032886505127,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep,grep -a Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5171597003936768,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.595801830291748,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5954360961914062,629,
|
||||
subtitles_en_literal,1,3,rg (lines),rg -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5945618152618408,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7291676998138428,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.730966329574585,629,
|
||||
subtitles_en_literal,1,3,ag (lines),ag -s Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.728854179382324,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.775996208190918,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7760195732116699,629,
|
||||
subtitles_en_literal,1,3,ucg (lines),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7763564586639404,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.433366060256958,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.4338581562042236,629,
|
||||
subtitles_en_literal,1,3,pt (lines),pt Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,3.435924768447876,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7586827278137207,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7590317726135254,629,
|
||||
subtitles_en_literal,1,3,sift (lines),sift -n Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.754432201385498,629,
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9726488590240479,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9699857234954834,629,LC_ALL=C
|
||||
subtitles_en_literal,1,3,grep (lines),grep -an Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9714112281799316,629,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.36658453941345215,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.3654778003692627,642,
|
||||
subtitles_en_literal_casei,1,3,rg,rg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.36565113067626953,642,
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.0890116691589355,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.08124852180481,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep,grep -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.0796849727630615,642,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6151647567749023,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6141552925109863,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,grep (ASCII),grep -E -ai Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6132988929748535,642,LC_ALL=C
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6962459087371826,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6945579051971436,642,
|
||||
subtitles_en_literal_casei,1,3,rg (lines),rg -n -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.693866491317749,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.771639823913574,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.772296190261841,642,
|
||||
subtitles_en_literal_casei,1,3,ag (lines) (ASCII),ag -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7712018489837646,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.8068230152130127,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.80411696434021,642,
|
||||
subtitles_en_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.8038516044616699,642,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5951778888702393,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5971941947937012,629,
|
||||
subtitles_en_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Sherlock Holmes(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5952184200286865,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7292284965515137,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.728681802749634,629,
|
||||
subtitles_en_literal_word,1,3,ag (ASCII),ag -sw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7315311431884766,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.784024715423584,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.780540943145752,629,
|
||||
subtitles_en_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.7772648334503174,629,
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9744353294372559,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9781327247619629,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,grep (ASCII),grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9798097610473633,629,LC_ALL=C
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5965189933776855,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5960156917572021,629,
|
||||
subtitles_en_literal_word,1,3,rg,rg -nw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.5975723266601562,629,
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9818971157073975,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.9785251617431641,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_literal_word,1,3,grep,grep -anw Sherlock Holmes /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.977081298828125,629,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.7750890254974365,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.774017333984375,13,
|
||||
subtitles_en_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.783200740814209,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.5396409034729004,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.5404820442199707,13,
|
||||
subtitles_en_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,2.5400590896606445,13,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,10.072888612747192,48,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,10.075153350830078,48,
|
||||
subtitles_en_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,10.0713791847229,48,
|
||||
subtitles_en_no_literal,1,3,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,7.734791278839111,13,
|
||||
subtitles_en_no_literal,1,3,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,7.7345263957977295,13,
|
||||
subtitles_en_no_literal,1,3,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,7.73199462890625,13,
|
||||
subtitles_en_no_literal,1,3,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.411367416381836,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,3,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.41072940826416,13,LC_ALL=C
|
||||
subtitles_en_no_literal,1,3,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.414730072021484,13,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6052529811859131,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6049232482910156,317,
|
||||
subtitles_en_surrounding_words,1,3,rg,rg -n \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6045565605163574,317,
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2849924564361572,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2837722301483154,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,grep,grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2847650051116943,317,LC_ALL=en_US.UTF-8
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6005992889404297,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.600543737411499,317,
|
||||
subtitles_en_surrounding_words,1,3,rg (ASCII),rg -n (?-u)\w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,0.6009273529052734,317,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,11.664374113082886,323,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,11.674306869506836,323,
|
||||
subtitles_en_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,11.657484769821167,323,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.650290012359619,317,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.651855707168579,317,
|
||||
subtitles_en_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,4.649921417236328,317,
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.2745037078857422,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.275665521621704,317,LC_ALL=C
|
||||
subtitles_en_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Holmes\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.sample.en,1.273988962173462,317,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.9031155109405518,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.9021081924438477,691,
|
||||
subtitles_ru_alternate,1,3,rg (lines),rg -n Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.9028818607330322,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.8895978927612305,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.891357660293579,691,
|
||||
subtitles_ru_alternate,1,3,ag (lines),ag -s Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.892467975616455,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7517757415771484,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7550888061523438,691,
|
||||
subtitles_ru_alternate,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7555651664733887,691,
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.51417875289917,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.512972116470337,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep (lines),grep -E -an Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.507266521453857,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.300950288772583,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.2987852096557617,691,
|
||||
subtitles_ru_alternate,1,3,rg,rg Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3024635314941406,691,
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,7.983739137649536,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,7.988446950912476,691,LC_ALL=C
|
||||
subtitles_ru_alternate,1,3,grep,grep -E -a Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,7.979671478271484,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.889382362365723,691,
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.902577877044678,691,
|
||||
subtitles_ru_alternate_casei,1,3,ag (ASCII),ag -s -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,5.890571355819702,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7548162937164307,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.747791051864624,691,
|
||||
subtitles_ru_alternate_casei,1,3,ucg (ASCII),ucg -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.7396674156188965,691,
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.58053183555603,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.594751596450806,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,grep (ASCII),grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.561670541763306,691,LC_ALL=C
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.833597183227539,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.831137180328369,735,
|
||||
subtitles_ru_alternate_casei,1,3,rg,rg -n -i Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.830361843109131,735,
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.723876953125,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.723239183425903,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_alternate_casei,1,3,grep,grep -E -ani Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.722000360488892,735,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.3252851963043213,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.3270294666290283,583,
|
||||
subtitles_ru_literal,1,3,rg,rg Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.32680773735046387,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.932488679885864,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.91330337524414,583,
|
||||
subtitles_ru_literal,1,3,pt,pt -N Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.911381006240845,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,16.438587427139282,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,16.412389755249023,583,
|
||||
subtitles_ru_literal,1,3,sift,sift Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,16.412444353103638,583,
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7865939140319824,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7889957427978516,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep,grep -a Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7923679351806641,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9255633354187012,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9285938739776611,583,
|
||||
subtitles_ru_literal,1,3,rg (lines),rg -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9274048805236816,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.4811036586761475,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.4785168170928955,583,
|
||||
subtitles_ru_literal,1,3,ag (lines),ag -s Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.484618186950684,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7743628025054932,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7731456756591797,583,
|
||||
subtitles_ru_literal,1,3,ucg (lines),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7749128341674805,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.931540250778198,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.935162782669067,583,
|
||||
subtitles_ru_literal,1,3,pt (lines),pt Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,12.949711561203003,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,17.183809995651245,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,17.19060492515564,583,
|
||||
subtitles_ru_literal,1,3,sift (lines),sift -n Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,17.17626404762268,583,
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3023960590362549,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.2992589473724365,583,LC_ALL=C
|
||||
subtitles_ru_literal,1,3,grep (lines),grep -an Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.299330711364746,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.1320264339447021,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.1323668956756592,604,
|
||||
subtitles_ru_literal_casei,1,3,rg,rg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.1354515552520752,604,
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.194744348526001,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.190656423568726,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep,grep -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,8.18506383895874,604,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7826528549194336,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7846219539642334,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,grep (ASCII),grep -E -ai Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7846999168395996,583,LC_ALL=C
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.734788179397583,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7333040237426758,604,
|
||||
subtitles_ru_literal_casei,1,3,rg (lines),rg -n -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.731860637664795,604,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7297205924987793,,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7314808368682861,,
|
||||
subtitles_ru_literal_casei,1,3,ag (lines) (ASCII),ag -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7289514541625977,,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7773914337158203,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.774536371231079,583,
|
||||
subtitles_ru_literal_casei,1,3,ucg (lines) (ASCII),ucg -i Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7740859985351562,583,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.3252553939819336,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.32543301582336426,,
|
||||
subtitles_ru_literal_word,1,3,rg (ASCII),rg -n (?-u:\b)Шерлок Холмс(?-u:\b) /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.32512736320495605,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7519562244415283,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.752692699432373,,
|
||||
subtitles_ru_literal_word,1,3,ag (ASCII),ag -sw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.7524521350860596,,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7868170738220215,583,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.7786612510681152,583,
|
||||
subtitles_ru_literal_word,1,3,ucg (ASCII),ucg --nosmart-case Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.776214838027954,583,
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.303652286529541,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3012151718139648,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,grep (ASCII),grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.307457685470581,583,LC_ALL=C
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9280951023101807,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9285900592803955,579,
|
||||
subtitles_ru_literal_word,1,3,rg,rg -nw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9288535118103027,579,
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3026466369628906,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3016819953918457,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_literal_word,1,3,grep,grep -anw Шерлок Холмс /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.3006587028503418,579,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.895586729049683,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.914353132247925,41,
|
||||
subtitles_ru_no_literal,1,3,rg,rg -n \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,4.902980327606201,41,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,3.972637891769409,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,3.9723849296569824,,
|
||||
subtitles_ru_no_literal,1,3,rg (ASCII),rg -n (?-u)\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,3.9723057746887207,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.3936586380004883,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.3987748622894287,,
|
||||
subtitles_ru_no_literal,1,3,ag (ASCII),ag -s \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.393911361694336,,
|
||||
subtitles_ru_no_literal,1,3,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.8932065963745117,,
|
||||
subtitles_ru_no_literal,1,3,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.8977222442626953,,
|
||||
subtitles_ru_no_literal,1,3,ucg (ASCII),ucg --nosmart-case \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.893040895462036,,
|
||||
subtitles_ru_no_literal,1,3,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.4844722747802734,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.485093116760254,,LC_ALL=C
|
||||
subtitles_ru_no_literal,1,3,grep (ASCII),grep -E -an \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5} /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.482459306716919,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9564735889434814,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9561436176300049,278,
|
||||
subtitles_ru_surrounding_words,1,3,rg,rg -n \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,0.9558789730072021,278,
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.6620113849639893,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.6624438762664795,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,grep,grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.6610260009765625,278,LC_ALL=en_US.UTF-8
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.4094629287719727,,
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.409822702407837,,
|
||||
subtitles_ru_surrounding_words,1,3,ag (ASCII),ag -s \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.4094691276550293,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.866976261138916,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.8666067123413086,,
|
||||
subtitles_ru_surrounding_words,1,3,ucg (ASCII),ucg --nosmart-case \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,2.865297317504883,,
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.602109670639038,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.598329782485962,,LC_ALL=C
|
||||
subtitles_ru_surrounding_words,1,3,grep (ASCII),grep -E -an \w+\s+Холмс\s+\w+ /mnt/bench/subtitles/OpenSubtitles2016.raw.ru,1.5975282192230225,,LC_ALL=C
|
|
226
benchsuite/runs/2016-09-17-ubuntu1604-ec2/summary
Normal file
226
benchsuite/runs/2016-09-17-ubuntu1604-ec2/summary
Normal file
@@ -0,0 +1,226 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.322 +/- 0.042 (lines: 68)
|
||||
ag (ignore) 1.754 +/- 0.006 (lines: 68)
|
||||
git grep (ignore) 0.502 +/- 0.004 (lines: 68)
|
||||
rg (whitelist)* 0.197 +/- 0.001 (lines: 68)*
|
||||
ucg (whitelist) 0.217 +/- 0.004 (lines: 68)
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.372 +/- 0.096 (lines: 160)
|
||||
ag (ignore) 1.965 +/- 0.009 (lines: 160)
|
||||
git grep (ignore) 2.022 +/- 0.001 (lines: 160)
|
||||
rg (whitelist)* 0.222 +/- 0.001 (lines: 160)*
|
||||
ucg (whitelist) 0.524 +/- 0.005 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.348 +/- 0.054 (lines: 16)
|
||||
rg (ignore) (mmap) 1.597 +/- 0.013 (lines: 16)
|
||||
ag (ignore) (mmap) 1.590 +/- 0.003 (lines: 16)
|
||||
pt (ignore) 0.455 +/- 0.015 (lines: 16)
|
||||
sift (ignore) 0.630 +/- 0.001 (lines: 16)
|
||||
git grep (ignore) 0.344 +/- 0.004 (lines: 16)
|
||||
rg (whitelist)* 0.253 +/- 0.077 (lines: 16)
|
||||
ucg (whitelist) 0.222 +/- 0.005 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.423 +/- 0.118 (lines: 370)
|
||||
rg (ignore) (mmap) 1.615 +/- 0.010 (lines: 370)
|
||||
ag (ignore) (mmap) 1.601 +/- 0.027 (lines: 370)
|
||||
sift (ignore) 0.804 +/- 0.003 (lines: 370)
|
||||
git grep (ignore) 0.346 +/- 0.004 (lines: 370)
|
||||
rg (whitelist) 0.234 +/- 0.032 (lines: 370)
|
||||
ucg (whitelist)* 0.220 +/- 0.008 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.277 +/- 0.002 (lines: 16)
|
||||
ag 1.594 +/- 0.008 (lines: 16)
|
||||
ucg* 0.219 +/- 0.007 (lines: 16)*
|
||||
pt 0.439 +/- 0.024 (lines: 16)
|
||||
sift 0.344 +/- 0.014 (lines: 16)
|
||||
git grep 0.344 +/- 0.005 (lines: 16)
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.581 +/- 0.002 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.408 +/- 0.008 (lines: 490)
|
||||
ag (ignore) (ASCII) 2.329 +/- 0.019 (lines: 766)
|
||||
sift (ignore) (ASCII) 25.756 +/- 0.113 (lines: 491)
|
||||
git grep (ignore) 26.344 +/- 0.005 (lines: 490)
|
||||
git grep (ignore) (ASCII) 4.152 +/- 0.004 (lines: 490)
|
||||
rg (whitelist) 0.502 +/- 0.008 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.346 +/- 0.035 (lines: 419)*
|
||||
ucg (whitelist) (ASCII) 1.127 +/- 0.001 (lines: 416)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.398 +/- 0.046 (lines: 1652)
|
||||
ag (ignore) 1.889 +/- 0.011 (lines: 1652)
|
||||
sift (ignore) 10.260 +/- 0.246 (lines: 1652)
|
||||
git grep (ignore) 1.107 +/- 0.001 (lines: 1652)
|
||||
rg (whitelist)* 0.206 +/- 0.001 (lines: 1630)*
|
||||
ucg (whitelist) 0.301 +/- 0.001 (lines: 1630)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.470 +/- 0.049 (lines: 23)*
|
||||
sift 7.715 +/- 0.125 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg 0.415 +/- 0.019 (lines: 103)
|
||||
sift* 0.002 +/- 0.000 (lines: 0)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.350 +/- 0.084 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.354 +/- 0.075 (lines: 174)
|
||||
ag (ignore) (ASCII) 1.770 +/- 0.005 (lines: 174)
|
||||
sift (ignore) (ASCII) 11.016 +/- 0.138 (lines: 174)
|
||||
git grep (ignore) 13.051 +/- 0.028 (lines: 186)
|
||||
git grep (ignore) (ASCII) 2.988 +/- 0.001 (lines: 174)
|
||||
rg (whitelist) 0.242 +/- 0.040 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.226 +/- 0.012 (lines: 168)
|
||||
ucg (ASCII) 0.225 +/- 0.002 (lines: 168)*
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.329 +/- 0.035 (lines: 6)
|
||||
ag (ignore) 1.598 +/- 0.016 (lines: 6)
|
||||
sift (ignore) 7.759 +/- 0.117 (lines: 6)
|
||||
git grep (ignore) 0.344 +/- 0.008 (lines: 6)
|
||||
rg (whitelist)* 0.269 +/- 0.059 (lines: 6)
|
||||
ucg (whitelist) 0.221 +/- 0.002 (lines: 6)*
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.620 +/- 0.002 (lines: 848)
|
||||
ag (lines) 3.756 +/- 0.000 (lines: 848)
|
||||
ucg (lines) 1.447 +/- 0.003 (lines: 848)
|
||||
grep (lines) 3.411 +/- 0.002 (lines: 848)
|
||||
rg* 0.290 +/- 0.000 (lines: 848)*
|
||||
grep 2.955 +/- 0.001 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.171 +/- 0.003 (lines: 862)
|
||||
ucg (ASCII) 3.417 +/- 0.001 (lines: 862)
|
||||
grep (ASCII) 4.529 +/- 0.003 (lines: 862)
|
||||
rg* 2.722 +/- 0.000 (lines: 862)*
|
||||
grep 5.121 +/- 0.001 (lines: 862)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.268 +/- 0.000 (lines: 629)*
|
||||
pt 3.437 +/- 0.003 (lines: 629)
|
||||
sift 0.327 +/- 0.001 (lines: 629)
|
||||
grep 0.519 +/- 0.002 (lines: 629)
|
||||
rg (lines) 0.595 +/- 0.001 (lines: 629)
|
||||
ag (lines) 2.730 +/- 0.001 (lines: 629)
|
||||
ucg (lines) 0.776 +/- 0.000 (lines: 629)
|
||||
pt (lines) 3.434 +/- 0.001 (lines: 629)
|
||||
sift (lines) 0.757 +/- 0.003 (lines: 629)
|
||||
grep (lines) 0.971 +/- 0.001 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.366 +/- 0.001 (lines: 642)*
|
||||
grep 4.083 +/- 0.005 (lines: 642)
|
||||
grep (ASCII) 0.614 +/- 0.001 (lines: 642)
|
||||
rg (lines) 0.695 +/- 0.001 (lines: 642)
|
||||
ag (lines) (ASCII) 2.772 +/- 0.001 (lines: 642)
|
||||
ucg (lines) (ASCII) 0.805 +/- 0.002 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII)* 0.596 +/- 0.001 (lines: 629)*
|
||||
ag (ASCII) 2.730 +/- 0.002 (lines: 629)
|
||||
ucg (ASCII) 0.781 +/- 0.003 (lines: 629)
|
||||
grep (ASCII) 0.977 +/- 0.003 (lines: 629)
|
||||
rg 0.597 +/- 0.001 (lines: 629)
|
||||
grep 0.979 +/- 0.002 (lines: 629)
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 2.777 +/- 0.005 (lines: 13)
|
||||
rg (ASCII)* 2.540 +/- 0.000 (lines: 13)*
|
||||
ag (ASCII) 10.073 +/- 0.002 (lines: 48)
|
||||
ucg (ASCII) 7.734 +/- 0.002 (lines: 13)
|
||||
grep (ASCII) 4.412 +/- 0.002 (lines: 13)
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.605 +/- 0.000 (lines: 317)
|
||||
grep 1.285 +/- 0.001 (lines: 317)
|
||||
rg (ASCII)* 0.601 +/- 0.000 (lines: 317)*
|
||||
ag (ASCII) 11.665 +/- 0.008 (lines: 323)
|
||||
ucg (ASCII) 4.651 +/- 0.001 (lines: 317)
|
||||
grep (ASCII) 1.275 +/- 0.001 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.903 +/- 0.001 (lines: 691)
|
||||
ag (lines) 5.891 +/- 0.001 (lines: 691)
|
||||
ucg (lines) 2.754 +/- 0.002 (lines: 691)
|
||||
grep (lines) 8.511 +/- 0.004 (lines: 691)
|
||||
rg* 1.301 +/- 0.002 (lines: 691)*
|
||||
grep 7.984 +/- 0.004 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.894 +/- 0.007 (lines: 691)
|
||||
ucg (ASCII)* 2.747 +/- 0.008 (lines: 691)*
|
||||
grep (ASCII) 8.579 +/- 0.017 (lines: 691)
|
||||
rg 4.832 +/- 0.002 (lines: 735)
|
||||
grep 8.723 +/- 0.001 (lines: 735)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.326 +/- 0.001 (lines: 583)*
|
||||
pt 12.919 +/- 0.012 (lines: 583)
|
||||
sift 16.421 +/- 0.015 (lines: 583)
|
||||
grep 0.789 +/- 0.003 (lines: 583)
|
||||
rg (lines) 0.927 +/- 0.002 (lines: 583)
|
||||
ag (lines) 4.481 +/- 0.003 (lines: 583)
|
||||
ucg (lines) 1.774 +/- 0.001 (lines: 583)
|
||||
pt (lines) 12.939 +/- 0.010 (lines: 583)
|
||||
sift (lines) 17.184 +/- 0.007 (lines: 583)
|
||||
grep (lines) 1.300 +/- 0.002 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.133 +/- 0.002 (lines: 604)
|
||||
grep 8.190 +/- 0.005 (lines: 604)
|
||||
grep (ASCII) 0.784 +/- 0.001 (lines: 583)
|
||||
rg (lines) 1.733 +/- 0.001 (lines: 604)
|
||||
ag (lines) (ASCII)* 0.730 +/- 0.001 (lines: 0)*
|
||||
ucg (lines) (ASCII) 1.775 +/- 0.002 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.325 +/- 0.000 (lines: 0)*
|
||||
ag (ASCII) 0.752 +/- 0.000 (lines: 0)
|
||||
ucg (ASCII) 1.781 +/- 0.006 (lines: 583)
|
||||
grep (ASCII) 1.304 +/- 0.003 (lines: 583)
|
||||
rg 0.929 +/- 0.000 (lines: 579)
|
||||
grep 1.302 +/- 0.001 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 4.904 +/- 0.009 (lines: 41)
|
||||
rg (ASCII) 3.972 +/- 0.000 (lines: 0)
|
||||
ag (ASCII)* 2.395 +/- 0.003 (lines: 0)*
|
||||
ucg (ASCII) 2.895 +/- 0.003 (lines: 0)
|
||||
grep (ASCII) 2.484 +/- 0.001 (lines: 0)
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.956 +/- 0.000 (lines: 278)*
|
||||
grep 1.662 +/- 0.001 (lines: 278)
|
||||
ag (ASCII) 2.410 +/- 0.000 (lines: 0)
|
||||
ucg (ASCII) 2.866 +/- 0.001 (lines: 0)
|
||||
grep (ASCII) 1.599 +/- 0.002 (lines: 0)
|
93
benchsuite/runs/2016-09-20-ubuntu1604-ec2/README.SETUP
Normal file
93
benchsuite/runs/2016-09-20-ubuntu1604-ec2/README.SETUP
Normal file
@@ -0,0 +1,93 @@
|
||||
Ubuntu 16.04 HVM AMI
|
||||
c3.2xlarge, Xeon E5-2680, 2.8 GHz, 8 CPUs, 16 GB memory, 80 GB SSD
|
||||
|
||||
# Generic system setup
|
||||
|
||||
mkfs.ext4 /dev/xvdb
|
||||
sudo mount /dev/xvdb /mnt
|
||||
sudo chown ubuntu /mnt
|
||||
sudo apt-get update
|
||||
sudo apt-get install \ # for building Linux kernel
|
||||
make gcc bc
|
||||
sudo apt-get install \ # for the silver searcher
|
||||
automake pkg-config zlib1g-dev liblzma-dev libpcre3 libpcre3-dev
|
||||
sudo apt-get install \ # for Universal Code Grep
|
||||
libtool libpcre2-8-0 libpcre2-dev
|
||||
sudo apt-get install \ # for sift and the platinum searcher
|
||||
go
|
||||
|
||||
# Get benchmark corpora
|
||||
|
||||
cd /mnt
|
||||
mkdir /mnt/bench
|
||||
git clone git://github.com/BurntSushi/ripgrep
|
||||
cd ripgrep/benchsuite
|
||||
./benchsuite --dir /mnt/bench/ --download all # takes around 15 minutes
|
||||
|
||||
# Install search tools
|
||||
mkdir /mnt/bin/
|
||||
|
||||
## ripgrep
|
||||
|
||||
cd /mnt
|
||||
mkdir ripgrep-bin
|
||||
cd ripgrep-bin
|
||||
curl -LO 'https://github.com/BurntSushi/ripgrep/releases/download/0.1.2/ripgrep-0.1.2-x86_64-unknown-linux-musl.tar.gz'
|
||||
cp ripgrep-0.1.2-x86_64-unknown-linux-musl/rg /mnt/bin/
|
||||
|
||||
## The Silver Searcher
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/ggreer/the_silver_searcher
|
||||
cd the_silver_searcher
|
||||
git checkout cda635
|
||||
./build.sh
|
||||
cp ag /mnt/bin/
|
||||
|
||||
## Universal Code Grep
|
||||
|
||||
cd /mnt
|
||||
git clone git://github.com/gvansickle/ucg
|
||||
cd ucg
|
||||
git checkout 487bfb
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ucg /mnt/bin/
|
||||
|
||||
## The Platinum Searcher
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/monochromegane/the_platinum_searcher
|
||||
cd /mnt/go/src/github.com/monochromegane/the_platinum_searcher
|
||||
git checkout 509368
|
||||
go install github.com/monochromegane/the_platinum_searcher/cmd/...
|
||||
cp /mnt/go/bin/pt /mnt/bin/
|
||||
|
||||
## Sift
|
||||
|
||||
export GOPATH=/mnt/go
|
||||
go get github.com/svent/sift
|
||||
cd /mnt/go/src/github.com/svent/sift
|
||||
git checkout 2d175c
|
||||
go install
|
||||
cp /mnt/go/bin/sift /mnt/bin/
|
||||
|
||||
## 'git grep' and GNU grep
|
||||
|
||||
They are part of the standard Ubuntu install, and are pretty recent (as of
|
||||
September 2016).
|
||||
|
||||
$ git --version
|
||||
git version 2.7.4
|
||||
$ grep --version
|
||||
grep (GNU grep) 2.25
|
||||
|
||||
|
||||
# Running benchmarks
|
||||
|
||||
export PATH="/mnt/bin:$PATH"
|
||||
cd /mnt/ripgrep/benchsuite
|
||||
./benchsuite \
|
||||
--dir /mnt/bench/ --raw /mnt/bench/raw.csv --warmup-iter 3 --bench-iter 10
|
||||
# The above took around 120 minutes to run to completion.
|
1591
benchsuite/runs/2016-09-20-ubuntu1604-ec2/raw.csv
Normal file
1591
benchsuite/runs/2016-09-20-ubuntu1604-ec2/raw.csv
Normal file
File diff suppressed because it is too large
Load Diff
233
benchsuite/runs/2016-09-20-ubuntu1604-ec2/summary
Normal file
233
benchsuite/runs/2016-09-20-ubuntu1604-ec2/summary
Normal file
@@ -0,0 +1,233 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg (ignore) 0.351 +/- 0.074 (lines: 68)
|
||||
ag (ignore) 1.747 +/- 0.005 (lines: 68)
|
||||
git grep (ignore) 0.501 +/- 0.003 (lines: 68)
|
||||
rg (whitelist)* 0.216 +/- 0.031 (lines: 68)
|
||||
ucg (whitelist) 0.214 +/- 0.008 (lines: 68)*
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg (ignore) 0.391 +/- 0.078 (lines: 160)
|
||||
ag (ignore) 1.968 +/- 0.009 (lines: 160)
|
||||
git grep (ignore) 2.018 +/- 0.006 (lines: 160)
|
||||
rg (whitelist)* 0.222 +/- 0.001 (lines: 160)*
|
||||
ucg (whitelist) 0.522 +/- 0.002 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg (ignore) 0.334 +/- 0.053 (lines: 16)
|
||||
rg (ignore) (mmap) 1.611 +/- 0.009 (lines: 16)
|
||||
ag (ignore) (mmap) 1.588 +/- 0.011 (lines: 16)
|
||||
pt (ignore) 0.456 +/- 0.025 (lines: 16)
|
||||
sift (ignore) 0.630 +/- 0.004 (lines: 16)
|
||||
git grep (ignore) 0.345 +/- 0.007 (lines: 16)
|
||||
rg (whitelist)* 0.228 +/- 0.042 (lines: 16)
|
||||
ucg (whitelist) 0.218 +/- 0.007 (lines: 16)*
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg (ignore) 0.345 +/- 0.073 (lines: 370)
|
||||
rg (ignore) (mmap) 1.612 +/- 0.011 (lines: 370)
|
||||
ag (ignore) (mmap) 1.609 +/- 0.015 (lines: 370)
|
||||
pt (ignore) 17.204 +/- 0.126 (lines: 370)
|
||||
sift (ignore) 0.805 +/- 0.005 (lines: 370)
|
||||
git grep (ignore) 0.343 +/- 0.007 (lines: 370)
|
||||
rg (whitelist)* 0.222 +/- 0.021 (lines: 370)
|
||||
ucg (whitelist) 0.217 +/- 0.006 (lines: 370)*
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.349 +/- 0.104 (lines: 16)
|
||||
ag 1.589 +/- 0.009 (lines: 16)
|
||||
ucg* 0.218 +/- 0.007 (lines: 16)*
|
||||
pt 0.462 +/- 0.012 (lines: 16)
|
||||
sift 0.352 +/- 0.018 (lines: 16)
|
||||
git grep 0.342 +/- 0.005 (lines: 16)
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg (ignore) 0.577 +/- 0.003 (lines: 490)
|
||||
rg (ignore) (ASCII) 0.416 +/- 0.025 (lines: 490)
|
||||
ag (ignore) (ASCII) 2.339 +/- 0.010 (lines: 766)
|
||||
pt (ignore) (ASCII) 22.066 +/- 0.057 (lines: 490)
|
||||
sift (ignore) (ASCII) 25.563 +/- 0.108 (lines: 490)
|
||||
git grep (ignore) 26.382 +/- 0.044 (lines: 490)
|
||||
git grep (ignore) (ASCII) 4.153 +/- 0.010 (lines: 490)
|
||||
rg (whitelist) 0.503 +/- 0.011 (lines: 419)
|
||||
rg (whitelist) (ASCII)* 0.343 +/- 0.038 (lines: 419)*
|
||||
ucg (whitelist) (ASCII) 1.130 +/- 0.003 (lines: 416)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg (ignore) 0.318 +/- 0.034 (lines: 1652)
|
||||
ag (ignore) 1.899 +/- 0.008 (lines: 1652)
|
||||
pt (ignore) 13.713 +/- 0.241 (lines: 1652)
|
||||
sift (ignore) 10.172 +/- 0.186 (lines: 1652)
|
||||
git grep (ignore) 1.108 +/- 0.004 (lines: 1652)
|
||||
rg (whitelist)* 0.221 +/- 0.022 (lines: 1630)*
|
||||
ucg (whitelist) 0.301 +/- 0.001 (lines: 1630)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.414 +/- 0.021 (lines: 23)*
|
||||
pt 12.745 +/- 0.166 (lines: 23)
|
||||
sift 7.767 +/- 0.264 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg 0.425 +/- 0.027 (lines: 103)
|
||||
pt 12.612 +/- 0.217 (lines: 23)
|
||||
sift* 0.002 +/- 0.000 (lines: 0)*
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg (ignore) 0.355 +/- 0.073 (lines: 186)
|
||||
rg (ignore) (ASCII) 0.329 +/- 0.060 (lines: 174)
|
||||
ag (ignore) (ASCII) 1.774 +/- 0.011 (lines: 174)
|
||||
pt (ignore) (ASCII) 14.180 +/- 0.180 (lines: 174)
|
||||
sift (ignore) (ASCII) 11.087 +/- 0.108 (lines: 174)
|
||||
git grep (ignore) 13.045 +/- 0.008 (lines: 186)
|
||||
git grep (ignore) (ASCII) 2.991 +/- 0.004 (lines: 174)
|
||||
rg (whitelist) 0.235 +/- 0.031 (lines: 180)
|
||||
rg (whitelist) (ASCII)* 0.225 +/- 0.023 (lines: 168)*
|
||||
ucg (ASCII) 0.229 +/- 0.007 (lines: 168)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg (ignore) 0.362 +/- 0.080 (lines: 6)
|
||||
ag (ignore) 1.603 +/- 0.009 (lines: 6)
|
||||
pt (ignore) 14.417 +/- 0.144 (lines: 6)
|
||||
sift (ignore) 7.840 +/- 0.123 (lines: 6)
|
||||
git grep (ignore) 0.341 +/- 0.005 (lines: 6)
|
||||
rg (whitelist)* 0.220 +/- 0.026 (lines: 6)*
|
||||
ucg (whitelist) 0.221 +/- 0.007 (lines: 6)
|
||||
|
||||
subtitles_en_alternate (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 0.619 +/- 0.001 (lines: 848)
|
||||
ag (lines) 3.757 +/- 0.001 (lines: 848)
|
||||
ucg (lines) 1.479 +/- 0.002 (lines: 848)
|
||||
grep (lines) 3.412 +/- 0.004 (lines: 848)
|
||||
rg* 0.294 +/- 0.001 (lines: 848)*
|
||||
grep 2.955 +/- 0.003 (lines: 848)
|
||||
|
||||
subtitles_en_alternate_casei (pattern: Sherlock Holmes|John Watson|Irene Adler|Inspector Lestrade|Professor Moriarty)
|
||||
---------------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.170 +/- 0.004 (lines: 862)
|
||||
ucg (ASCII) 3.453 +/- 0.005 (lines: 862)
|
||||
grep (ASCII) 4.537 +/- 0.025 (lines: 862)
|
||||
rg* 2.724 +/- 0.002 (lines: 862)*
|
||||
grep 5.125 +/- 0.006 (lines: 862)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg* 0.269 +/- 0.000 (lines: 629)*
|
||||
pt 3.436 +/- 0.001 (lines: 629)
|
||||
sift 0.327 +/- 0.002 (lines: 629)
|
||||
grep 0.517 +/- 0.001 (lines: 629)
|
||||
rg (lines) 0.596 +/- 0.001 (lines: 629)
|
||||
ag (lines) 2.730 +/- 0.003 (lines: 629)
|
||||
ucg (lines) 0.814 +/- 0.003 (lines: 629)
|
||||
pt (lines) 3.438 +/- 0.004 (lines: 629)
|
||||
sift (lines) 0.759 +/- 0.003 (lines: 629)
|
||||
grep (lines) 0.971 +/- 0.001 (lines: 629)
|
||||
|
||||
subtitles_en_literal_casei (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------------
|
||||
rg* 0.366 +/- 0.001 (lines: 642)*
|
||||
grep 4.084 +/- 0.005 (lines: 642)
|
||||
grep (ASCII) 0.614 +/- 0.001 (lines: 642)
|
||||
rg (lines) 0.696 +/- 0.002 (lines: 642)
|
||||
ag (lines) (ASCII) 2.775 +/- 0.004 (lines: 642)
|
||||
ucg (lines) (ASCII) 0.841 +/- 0.002 (lines: 642)
|
||||
|
||||
subtitles_en_literal_word (pattern: Sherlock Holmes)
|
||||
----------------------------------------------------
|
||||
rg (ASCII) 0.596 +/- 0.001 (lines: 629)
|
||||
ag (ASCII) 2.729 +/- 0.001 (lines: 629)
|
||||
ucg (ASCII) 0.810 +/- 0.002 (lines: 629)
|
||||
grep (ASCII) 0.970 +/- 0.000 (lines: 629)
|
||||
rg* 0.596 +/- 0.001 (lines: 629)*
|
||||
grep 0.972 +/- 0.003 (lines: 629)
|
||||
|
||||
subtitles_en_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 2.777 +/- 0.003 (lines: 13)
|
||||
rg (ASCII)* 2.541 +/- 0.005 (lines: 13)*
|
||||
ag (ASCII) 10.076 +/- 0.005 (lines: 48)
|
||||
ucg (ASCII) 7.771 +/- 0.004 (lines: 13)
|
||||
grep (ASCII) 4.411 +/- 0.004 (lines: 13)
|
||||
|
||||
subtitles_en_surrounding_words (pattern: \w+\s+Holmes\s+\w+)
|
||||
------------------------------------------------------------
|
||||
rg 0.605 +/- 0.000 (lines: 317)
|
||||
grep 1.286 +/- 0.002 (lines: 317)
|
||||
rg (ASCII)* 0.602 +/- 0.000 (lines: 317)*
|
||||
ag (ASCII) 11.663 +/- 0.008 (lines: 323)
|
||||
ucg (ASCII) 4.690 +/- 0.002 (lines: 317)
|
||||
grep (ASCII) 1.276 +/- 0.002 (lines: 317)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg (lines) 1.902 +/- 0.002 (lines: 691)
|
||||
ag (lines) 5.892 +/- 0.003 (lines: 691)
|
||||
ucg (lines) 2.864 +/- 0.006 (lines: 691)
|
||||
grep (lines) 8.511 +/- 0.005 (lines: 691)
|
||||
rg* 1.300 +/- 0.002 (lines: 691)*
|
||||
grep 7.994 +/- 0.017 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
ag (ASCII) 5.891 +/- 0.001 (lines: 691)
|
||||
ucg (ASCII)* 2.868 +/- 0.005 (lines: 691)*
|
||||
grep (ASCII) 8.572 +/- 0.009 (lines: 691)
|
||||
rg 4.834 +/- 0.004 (lines: 735)
|
||||
grep 8.729 +/- 0.004 (lines: 735)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg* 0.326 +/- 0.001 (lines: 583)*
|
||||
pt 12.922 +/- 0.010 (lines: 583)
|
||||
sift 16.424 +/- 0.010 (lines: 583)
|
||||
grep 0.786 +/- 0.003 (lines: 583)
|
||||
rg (lines) 0.927 +/- 0.002 (lines: 583)
|
||||
ag (lines) 4.481 +/- 0.003 (lines: 583)
|
||||
ucg (lines) 1.897 +/- 0.009 (lines: 583)
|
||||
pt (lines) 12.937 +/- 0.006 (lines: 583)
|
||||
sift (lines) 17.178 +/- 0.008 (lines: 583)
|
||||
grep (lines) 1.301 +/- 0.005 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.131 +/- 0.001 (lines: 604)
|
||||
grep 8.187 +/- 0.006 (lines: 604)
|
||||
grep (ASCII) 0.785 +/- 0.001 (lines: 583)
|
||||
rg (lines) 1.733 +/- 0.002 (lines: 604)
|
||||
ag (lines) (ASCII)* 0.729 +/- 0.001 (lines: 0)*
|
||||
ucg (lines) (ASCII) 1.896 +/- 0.005 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_word (pattern: Шерлок Холмс)
|
||||
-------------------------------------------------
|
||||
rg (ASCII)* 0.325 +/- 0.000 (lines: 0)*
|
||||
ag (ASCII) 0.753 +/- 0.001 (lines: 0)
|
||||
ucg (ASCII) 1.891 +/- 0.004 (lines: 583)
|
||||
grep (ASCII) 1.303 +/- 0.004 (lines: 583)
|
||||
rg 0.929 +/- 0.001 (lines: 579)
|
||||
grep 1.304 +/- 0.003 (lines: 579)
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 4.905 +/- 0.003 (lines: 41)
|
||||
rg (ASCII) 3.973 +/- 0.002 (lines: 0)
|
||||
ag (ASCII)* 2.395 +/- 0.004 (lines: 0)*
|
||||
ucg (ASCII) 3.006 +/- 0.005 (lines: 0)
|
||||
grep (ASCII) 2.483 +/- 0.005 (lines: 0)
|
||||
|
||||
subtitles_ru_surrounding_words (pattern: \w+\s+Холмс\s+\w+)
|
||||
-----------------------------------------------------------
|
||||
rg* 0.957 +/- 0.001 (lines: 278)*
|
||||
grep 1.660 +/- 0.002 (lines: 278)
|
||||
ag (ASCII) 2.411 +/- 0.001 (lines: 0)
|
||||
ucg (ASCII) 2.980 +/- 0.002 (lines: 0)
|
||||
grep (ASCII) 1.596 +/- 0.003 (lines: 0)
|
164
benchsuite/summary
Normal file
164
benchsuite/summary
Normal file
@@ -0,0 +1,164 @@
|
||||
linux_alternates (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------
|
||||
rg 0.239 +/- 0.008 (lines: 68)
|
||||
rg-novcs* 0.122 +/- 0.018 (lines: 68)*
|
||||
rg-novcs-mmap 0.394 +/- 0.004 (lines: 68)
|
||||
ag 0.497 +/- 0.009 (lines: 68)
|
||||
ag-novcs 0.554 +/- 0.125 (lines: 68)
|
||||
ucg 0.153 +/- 0.004 (lines: 68)
|
||||
git grep 0.254 +/- 0.011 (lines: 68)
|
||||
|
||||
linux_alternates_casei (pattern: ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT)
|
||||
-------------------------------------------------------------------------------
|
||||
rg 0.230 +/- 0.015 (lines: 160)
|
||||
rg-novcs* 0.126 +/- 0.003 (lines: 160)*
|
||||
rg-novcs-mmap 0.397 +/- 0.004 (lines: 160)
|
||||
ag 0.826 +/- 0.377 (lines: 160)
|
||||
ag-novcs 0.592 +/- 0.047 (lines: 160)
|
||||
ucg 0.238 +/- 0.002 (lines: 160)
|
||||
git grep 0.920 +/- 0.054 (lines: 160)
|
||||
|
||||
linux_literal (pattern: PM_RESUME)
|
||||
----------------------------------
|
||||
rg 0.218 +/- 0.003 (lines: 16)
|
||||
rg-novcs* 0.109 +/- 0.011 (lines: 16)*
|
||||
rg-novcs-mmap 0.389 +/- 0.007 (lines: 16)
|
||||
ag 0.512 +/- 0.005 (lines: 16)
|
||||
ag-novcs 0.876 +/- 0.370 (lines: 16)
|
||||
ucg 0.163 +/- 0.004 (lines: 16)
|
||||
git grep 0.194 +/- 0.001 (lines: 16)
|
||||
pt 0.197 +/- 0.019 (lines: 16)
|
||||
sift 0.142 +/- 0.002 (lines: 16)
|
||||
|
||||
linux_literal_casei (pattern: PM_RESUME)
|
||||
----------------------------------------
|
||||
rg 0.267 +/- 0.054 (lines: 370)
|
||||
rg-novcs* 0.122 +/- 0.015 (lines: 399)*
|
||||
rg-novcs-mmap 0.403 +/- 0.010 (lines: 399)
|
||||
ag 0.428 +/- 0.026 (lines: 370)
|
||||
ag-novcs 0.440 +/- 0.019 (lines: 399)
|
||||
ucg 0.157 +/- 0.002 (lines: 370)
|
||||
git grep 0.183 +/- 0.005 (lines: 370)
|
||||
sift 0.203 +/- 0.005 (lines: 399)
|
||||
|
||||
linux_literal_default (pattern: PM_RESUME)
|
||||
------------------------------------------
|
||||
rg 0.232 +/- 0.024 (lines: 16)
|
||||
ag 0.460 +/- 0.056 (lines: 16)
|
||||
ucg 0.165 +/- 0.001 (lines: 16)
|
||||
git grep 0.187 +/- 0.020 (lines: 16)
|
||||
pt 0.156 +/- 0.001 (lines: 16)
|
||||
sift* 0.117 +/- 0.000 (lines: 16)*
|
||||
|
||||
linux_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
-----------------------------------------------------------------
|
||||
rg 0.393 +/- 0.008 (lines: 490)
|
||||
rg-whitelist 0.325 +/- 0.002 (lines: 419)
|
||||
rg (no Unicode) 0.304 +/- 0.026 (lines: 490)
|
||||
rg-whitelist (no Unicode)* 0.227 +/- 0.009 (lines: 419)*
|
||||
ag (no Unicode) 0.809 +/- 0.102 (lines: 766)
|
||||
ag-novcs (no Unicode) 0.703 +/- 0.012 (lines: 767)
|
||||
ucg (no Unicode) 0.443 +/- 0.002 (lines: 416)
|
||||
git grep 9.576 +/- 0.465 (lines: 490)
|
||||
git grep (no Unicode) 2.046 +/- 0.236 (lines: 490)
|
||||
sift (no Unicode) 8.894 +/- 0.086 (lines: 491)
|
||||
|
||||
linux_re_literal_suffix (pattern: [A-Z]+_RESUME)
|
||||
------------------------------------------------
|
||||
rg 0.216 +/- 0.001 (lines: 1652)
|
||||
rg-novcs* 0.102 +/- 0.002 (lines: 1653)*
|
||||
rg-novcs-mmap 0.401 +/- 0.015 (lines: 1653)
|
||||
ag 1.399 +/- 0.556 (lines: 1652)
|
||||
ag-novcs 0.523 +/- 0.016 (lines: 1653)
|
||||
ucg 0.140 +/- 0.003 (lines: 1630)
|
||||
git grep 0.561 +/- 0.027 (lines: 1652)
|
||||
sift 4.092 +/- 0.164 (lines: 1653)
|
||||
|
||||
linux_unicode_greek (pattern: \p{Greek})
|
||||
----------------------------------------
|
||||
rg* 0.291 +/- 0.006 (lines: 23)*
|
||||
sift 2.822 +/- 0.016 (lines: 23)
|
||||
|
||||
linux_unicode_greek_casei (pattern: \p{Greek})
|
||||
----------------------------------------------
|
||||
rg* 0.324 +/- 0.037 (lines: 103)*
|
||||
sift 2.925 +/- 0.053 (lines: 23)
|
||||
|
||||
linux_unicode_word (pattern: \wAh)
|
||||
----------------------------------
|
||||
rg 0.235 +/- 0.033 (lines: 186)
|
||||
rg (no Unicode) 0.234 +/- 0.002 (lines: 174)
|
||||
rg-novcs* 0.112 +/- 0.003 (lines: 186)*
|
||||
rg-novcs-mmap 0.400 +/- 0.005 (lines: 186)
|
||||
ag (no Unicode) 0.937 +/- 0.004 (lines: 174)
|
||||
ag-novcs (no Unicode) 0.922 +/- 0.030 (lines: 174)
|
||||
ucg (no Unicode) 0.175 +/- 0.005 (lines: 168)
|
||||
git grep 4.972 +/- 0.028 (lines: 186)
|
||||
git grep (no Unicode) 1.566 +/- 0.038 (lines: 174)
|
||||
sift (no Unicode) 4.195 +/- 0.141 (lines: 174)
|
||||
|
||||
linux_word (pattern: PM_RESUME)
|
||||
-------------------------------
|
||||
rg 0.224 +/- 0.014 (lines: 6)
|
||||
rg-novcs* 0.116 +/- 0.028 (lines: 6)*
|
||||
rg-novcs-mmap 0.395 +/- 0.007 (lines: 6)
|
||||
ag 0.571 +/- 0.141 (lines: 6)
|
||||
ag-novcs 0.437 +/- 0.030 (lines: 6)
|
||||
ucg 0.163 +/- 0.002 (lines: 6)
|
||||
git grep 0.180 +/- 0.014 (lines: 6)
|
||||
sift 3.161 +/- 0.058 (lines: 6)
|
||||
|
||||
subtitles_en_literal (pattern: Sherlock Holmes)
|
||||
-----------------------------------------------
|
||||
rg 0.487 +/- 0.058 (lines: 629)
|
||||
rg (no line numbers)* 0.237 +/- 0.028 (lines: 629)*
|
||||
ag 2.002 +/- 0.003 (lines: 629)
|
||||
ucg 0.721 +/- 0.052 (lines: 629)
|
||||
grep 1.010 +/- 0.021 (lines: 629)
|
||||
grep (no line numbers) 0.560 +/- 0.046 (lines: 629)
|
||||
pt 1.669 +/- 0.020 (lines: 629)
|
||||
pt (no line numbers) 1.597 +/- 0.092 (lines: 629)
|
||||
sift 0.684 +/- 0.085 (lines: 629)
|
||||
sift (no line numbers) 0.270 +/- 0.006 (lines: 629)
|
||||
|
||||
subtitles_ru_alternate (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
rg 1.664 +/- 0.092 (lines: 691)
|
||||
rg (no line numbers)* 1.290 +/- 0.053 (lines: 691)*
|
||||
ucg 2.382 +/- 0.016 (lines: 691)
|
||||
grep 6.861 +/- 0.127 (lines: 691)
|
||||
grep (no line numbers) 6.426 +/- 0.156 (lines: 691)
|
||||
|
||||
subtitles_ru_alternate_casei (pattern: Шерлок Холмс|Джон Уотсон|Ирен Адлер|инспектор Лестрейд|профессор Мориарти)
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
rg 4.119 +/- 0.102 (lines: 735)
|
||||
ucg (not Unicode)* 2.344 +/- 0.098 (lines: 691)*
|
||||
grep 6.902 +/- 0.113 (lines: 735)
|
||||
grep (not Unicode) 6.902 +/- 0.096 (lines: 691)
|
||||
|
||||
subtitles_ru_literal (pattern: Шерлок Холмс)
|
||||
--------------------------------------------
|
||||
rg 0.852 +/- 0.038 (lines: 583)
|
||||
rg (no line numbers)* 0.304 +/- 0.009 (lines: 583)*
|
||||
ag 3.010 +/- 0.132 (lines: 583)
|
||||
ucg 1.557 +/- 0.048 (lines: 583)
|
||||
grep 1.335 +/- 0.003 (lines: 583)
|
||||
grep (no line numbers) 0.876 +/- 0.003 (lines: 583)
|
||||
pt 5.319 +/- 0.339 (lines: 583)
|
||||
pt (no line numbers) 5.325 +/- 0.171 (lines: 583)
|
||||
sift 6.876 +/- 0.060 (lines: 583)
|
||||
sift (no line numbers) 6.311 +/- 0.065 (lines: 583)
|
||||
|
||||
subtitles_ru_literal_casei (pattern: Шерлок Холмс)
|
||||
--------------------------------------------------
|
||||
rg 1.635 +/- 0.153 (lines: 604)
|
||||
ucg (not Unicode) 1.571 +/- 0.042 (lines: 583)
|
||||
grep 6.729 +/- 0.241 (lines: 604)
|
||||
grep (not Unicode)* 1.209 +/- 0.115 (lines: 583)*
|
||||
|
||||
subtitles_ru_no_literal (pattern: \w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5}\s+\w{5})
|
||||
----------------------------------------------------------------------------------------
|
||||
rg 3.834 +/- 0.081 (lines: 41)
|
||||
rg (no line numbers) 3.443 +/- 0.025 (lines: 41)
|
||||
ucg (no Unicode) 2.246 +/- 0.096 (lines: 0)
|
||||
grep (no Unicode)* 1.951 +/- 0.107 (lines: 0)*
|
25
ci/sha256.sh
Normal file
25
ci/sha256.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# != 1 ]; then
|
||||
echo "Usage: $(basename $0) version" >&2
|
||||
exit 1
|
||||
fi
|
||||
version="$1"
|
||||
|
||||
# Linux and Darwin builds.
|
||||
for arch in i686 x86_64; do
|
||||
for target in apple-darwin unknown-linux-musl; do
|
||||
url="https://github.com/BurntSushi/ripgrep/releases/download/$version/ripgrep-$version-$arch-$target.tar.gz"
|
||||
sha=$(curl -sfSL "$url" | sha256sum)
|
||||
echo "$version-$arch-$target $sha"
|
||||
done
|
||||
done
|
||||
|
||||
# Source.
|
||||
for ext in zip tar.gz; do
|
||||
url="https://github.com/BurntSushi/ripgrep/archive/$version.$ext"
|
||||
sha=$(curl -sfSL "$url" | sha256sum)
|
||||
echo "source.$ext $sha"
|
||||
done
|
11
ctags.rust
11
ctags.rust
@@ -1,11 +0,0 @@
|
||||
--langdef=Rust
|
||||
--langmap=Rust:.rs
|
||||
--regex-Rust=/^[ \t]*(#\[[^\]]\][ \t]*)*(pub[ \t]+)?(extern[ \t]+)?("[^"]+"[ \t]+)?(unsafe[ \t]+)?fn[ \t]+([a-zA-Z0-9_]+)/\6/f,functions,function definitions/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?type[ \t]+([a-zA-Z0-9_]+)/\2/T,types,type definitions/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?enum[ \t]+([a-zA-Z0-9_]+)/\2/g,enum,enumeration names/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?struct[ \t]+([a-zA-Z0-9_]+)/\2/s,structure names/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?mod[ \t]+([a-zA-Z0-9_]+)/\2/m,modules,module names/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?static[ \t]+([a-zA-Z0-9_]+)/\2/c,consts,static constants/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?trait[ \t]+([a-zA-Z0-9_]+)/\2/t,traits,traits/
|
||||
--regex-Rust=/^[ \t]*(pub[ \t]+)?impl([ \t\n]+<.*>)?[ \t]+([a-zA-Z0-9_]+)/\3/i,impls,trait implementations/
|
||||
--regex-Rust=/^[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/d,macros,macro definitions/
|
@@ -1,12 +1,11 @@
|
||||
[package]
|
||||
publish = false
|
||||
name = "grep"
|
||||
version = "0.1.0" #:version
|
||||
version = "0.1.2" #:version
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = """
|
||||
Fast line oriented regex searching as a library.
|
||||
"""
|
||||
documentation = "https://github.com/BurntSushi/ripgrep"
|
||||
documentation = "http://burntsushi.net/rustdoc/grep/"
|
||||
homepage = "https://github.com/BurntSushi/ripgrep"
|
||||
repository = "https://github.com/BurntSushi/ripgrep"
|
||||
readme = "README.md"
|
||||
@@ -17,5 +16,5 @@ license = "Unlicense/MIT"
|
||||
log = "0.3"
|
||||
memchr = "0.1"
|
||||
memmap = "0.2"
|
||||
regex = "0.1.75"
|
||||
regex = "0.1.77"
|
||||
regex-syntax = "0.3.5"
|
||||
|
4
grep/README.md
Normal file
4
grep/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
grep
|
||||
----
|
||||
This is a *library* that provides grep-style line-by-line regex searching (with
|
||||
comparable performance to `grep` itself).
|
@@ -19,6 +19,7 @@ pub use search::{Grep, GrepBuilder, Iter, Match};
|
||||
mod literals;
|
||||
mod nonl;
|
||||
mod search;
|
||||
mod word_boundary;
|
||||
|
||||
/// Result is a convenient type alias that fixes the type of the error to
|
||||
/// the `Error` type defined in this crate.
|
||||
@@ -62,7 +63,7 @@ impl fmt::Display for Error {
|
||||
match *self {
|
||||
Error::Regex(ref err) => err.fmt(f),
|
||||
Error::LiteralNotAllowed(chr) => {
|
||||
write!(f, "Literal '{}' not allowed.", chr)
|
||||
write!(f, "Literal {:?} not allowed.", chr)
|
||||
}
|
||||
Error::__Nonexhaustive => unreachable!(),
|
||||
}
|
||||
|
@@ -10,6 +10,10 @@ use {Error, Result};
|
||||
/// If `byte` is not an ASCII character (i.e., greater than `0x7F`), then this
|
||||
/// function panics.
|
||||
pub fn remove(expr: Expr, byte: u8) -> Result<Expr> {
|
||||
// TODO(burntsushi): There is a bug in this routine where only `\n` is
|
||||
// handled correctly. Namely, `AnyChar` and `AnyByte` need to be translated
|
||||
// to proper character classes instead of the special `AnyCharNoNL` and
|
||||
// `AnyByteNoNL` classes.
|
||||
use syntax::Expr::*;
|
||||
assert!(byte <= 0x7F);
|
||||
let chr = byte as char;
|
||||
|
@@ -4,6 +4,8 @@ use syntax;
|
||||
|
||||
use literals::LiteralSets;
|
||||
use nonl;
|
||||
use syntax::Expr;
|
||||
use word_boundary::strip_unicode_word_boundaries;
|
||||
use Result;
|
||||
|
||||
/// A matched line.
|
||||
@@ -127,22 +129,35 @@ impl GrepBuilder {
|
||||
pub fn build(self) -> Result<Grep> {
|
||||
let expr = try!(self.parse());
|
||||
let literals = LiteralSets::create(&expr);
|
||||
let re = try!(
|
||||
RegexBuilder::new(&expr.to_string())
|
||||
.case_insensitive(self.opts.case_insensitive)
|
||||
.multi_line(true)
|
||||
.unicode(true)
|
||||
.size_limit(self.opts.size_limit)
|
||||
.dfa_size_limit(self.opts.dfa_size_limit)
|
||||
.compile()
|
||||
);
|
||||
let re = try!(self.regex(&expr));
|
||||
let required = literals.to_regex().or_else(|| {
|
||||
let expr = match strip_unicode_word_boundaries(&expr) {
|
||||
None => return None,
|
||||
Some(expr) => expr,
|
||||
};
|
||||
debug!("Stripped Unicode word boundaries. New AST:\n{:?}", expr);
|
||||
self.regex(&expr).ok()
|
||||
});
|
||||
Ok(Grep {
|
||||
re: re,
|
||||
required: literals.to_regex(),
|
||||
required: required,
|
||||
opts: self.opts,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a new regex from the given expression with the current
|
||||
/// configuration.
|
||||
fn regex(&self, expr: &Expr) -> Result<Regex> {
|
||||
RegexBuilder::new(&expr.to_string())
|
||||
.case_insensitive(self.opts.case_insensitive)
|
||||
.multi_line(true)
|
||||
.unicode(true)
|
||||
.size_limit(self.opts.size_limit)
|
||||
.dfa_size_limit(self.opts.dfa_size_limit)
|
||||
.compile()
|
||||
.map_err(From::from)
|
||||
}
|
||||
|
||||
/// Parses the underlying pattern and ensures the pattern can never match
|
||||
/// the line terminator.
|
||||
fn parse(&self) -> Result<syntax::Expr> {
|
||||
|
54
grep/src/word_boundary.rs
Normal file
54
grep/src/word_boundary.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use syntax::Expr;
|
||||
|
||||
/// Strips Unicode word boundaries from the given expression.
|
||||
///
|
||||
/// The key invariant this maintains is that the expression returned will match
|
||||
/// *at least* every where the expression given will match. Namely, a match of
|
||||
/// the returned expression can report false positives but it will never report
|
||||
/// false negatives.
|
||||
///
|
||||
/// If no word boundaries could be stripped, then None is returned.
|
||||
pub fn strip_unicode_word_boundaries(expr: &Expr) -> Option<Expr> {
|
||||
// The real reason we do this is because Unicode word boundaries are the
|
||||
// one thing that Rust's regex DFA engine can't handle. When it sees a
|
||||
// Unicode word boundary among non-ASCII text, it falls back to one of the
|
||||
// slower engines. We work around this limitation by attempting to use
|
||||
// a regex to find candidate matches without a Unicode word boundary. We'll
|
||||
// only then use the full (and slower) regex to confirm a candidate as a
|
||||
// match or not during search.
|
||||
use syntax::Expr::*;
|
||||
|
||||
match *expr {
|
||||
Concat(ref es) if !es.is_empty() => {
|
||||
let first = is_unicode_word_boundary(&es[0]);
|
||||
let last = is_unicode_word_boundary(es.last().unwrap());
|
||||
// Be careful not to strip word boundaries if there are no other
|
||||
// expressions to match.
|
||||
match (first, last) {
|
||||
(true, false) if es.len() > 1 => {
|
||||
Some(Concat(es[1..].to_vec()))
|
||||
}
|
||||
(false, true) if es.len() > 1 => {
|
||||
Some(Concat(es[..es.len() - 1].to_vec()))
|
||||
}
|
||||
(true, true) if es.len() > 2 => {
|
||||
Some(Concat(es[1..es.len() - 1].to_vec()))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the given expression is a Unicode word boundary.
|
||||
fn is_unicode_word_boundary(expr: &Expr) -> bool {
|
||||
use syntax::Expr::*;
|
||||
|
||||
match *expr {
|
||||
WordBoundary => true,
|
||||
NotWordBoundary => true,
|
||||
Group { ref e, .. } => is_unicode_word_boundary(e),
|
||||
_ => false,
|
||||
}
|
||||
}
|
35
pkg/archlinux/PKGBUILD
Normal file
35
pkg/archlinux/PKGBUILD
Normal file
@@ -0,0 +1,35 @@
|
||||
# Contributor: Andrew Gallant <jamslam@gmail.com>
|
||||
# Maintainer: Andrew Gallant
|
||||
pkgname=ripgrep
|
||||
pkgver=0.1.11
|
||||
pkgrel=1
|
||||
pkgdesc="A search tool that combines the usability of The Silver Searcher with the raw speed of grep."
|
||||
arch=('i686' 'x86_64')
|
||||
url="https://github.com/BurntSushi/ripgrep"
|
||||
license=('UNLICENSE')
|
||||
makedepends=('cargo')
|
||||
source=("https://github.com/BurntSushi/$pkgname/archive/$pkgver.tar.gz")
|
||||
sha256sums=('d29beb1a43a263d75ce4ef23a07253ed6ea306b14ffb5b37bc4972fb5d98238c')
|
||||
|
||||
build() {
|
||||
cd "$pkgname-$pkgver"
|
||||
if command -v rustup > /dev/null 2>&1; then
|
||||
RUSTFLAGS="-C target-cpu=native" rustup run nightly \
|
||||
cargo build --release --features simd-accel
|
||||
elif rustc --version | grep -q nightly; then
|
||||
RUSTFLAGS="-C target-cpu=native" \
|
||||
cargo build --release --features simd-accel
|
||||
else
|
||||
cargo build --release
|
||||
fi
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$pkgname-$pkgver"
|
||||
|
||||
install -Dm755 "target/release/rg" "$pkgdir/usr/bin/rg"
|
||||
install -Dm644 "README-NEW.md" "$pkgdir/usr/share/doc/ripgrep/README.md"
|
||||
install -Dm644 "COPYING" "$pkgdir/usr/share/doc/ripgrep/COPYING"
|
||||
install -Dm644 "LICENSE-MIT" "$pkgdir/usr/share/doc/ripgrep/LICENSE-MIT"
|
||||
install -Dm644 "UNLICENSE" "$pkgdir/usr/share/doc/ripgrep/UNLICENSE"
|
||||
}
|
18
pkg/brew/ripgrep.rb
Normal file
18
pkg/brew/ripgrep.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require 'formula'
|
||||
class Ripgrep < Formula
|
||||
version '0.1.8'
|
||||
desc "Search tool like grep and The Silver Searcher."
|
||||
homepage "https://github.com/BurntSushi/ripgrep"
|
||||
|
||||
if Hardware::CPU.is_64_bit?
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "893e0e7fac88ebbef024829466fafef6eae5b1060273bbfca3806090e660b06b"
|
||||
else
|
||||
url "https://github.com/BurntSushi/ripgrep/releases/download/#{version}/ripgrep-#{version}-i686-apple-darwin.tar.gz"
|
||||
sha256 "2296c8081a2bfe28b43dea4326a9e8ce9c2821fd628a1ca366e824aceddc5fad"
|
||||
end
|
||||
|
||||
def install
|
||||
bin.install "rg"
|
||||
end
|
||||
end
|
@@ -1 +0,0 @@
|
||||
au BufWritePost *.rs silent!make ctags > /dev/null 2>&1
|
136
src/args.rs
136
src/args.rs
@@ -10,15 +10,21 @@ use log;
|
||||
use num_cpus;
|
||||
use regex;
|
||||
use term::Terminal;
|
||||
#[cfg(not(windows))]
|
||||
use term;
|
||||
#[cfg(windows)]
|
||||
use term::WinConsole;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use atty;
|
||||
use gitignore::{Gitignore, GitignoreBuilder};
|
||||
use ignore::Ignore;
|
||||
use out::{Out, OutBuffer};
|
||||
use out::{Out, ColoredTerminal};
|
||||
use printer::Printer;
|
||||
use search_buffer::BufferSearcher;
|
||||
use search_stream::{InputBuffer, Searcher};
|
||||
#[cfg(windows)]
|
||||
use terminal_win::WindowsBuffer;
|
||||
use types::{FileTypeDef, Types, TypesBuilder};
|
||||
use walk;
|
||||
|
||||
@@ -29,13 +35,14 @@ use Result;
|
||||
/// If you've never heard of Docopt before, see: http://docopt.org
|
||||
/// (TL;DR: The CLI parser is generated from the usage string below.)
|
||||
const USAGE: &'static str = "
|
||||
Usage: rg [options] <pattern> [<path> ...]
|
||||
Usage: rg [options] -e PATTERN ... [<path> ...]
|
||||
rg [options] <pattern> [<path> ...]
|
||||
rg [options] --files [<path> ...]
|
||||
rg [options] --type-list
|
||||
rg --help
|
||||
rg --version
|
||||
|
||||
rg combines the usability of the silver search with the raw speed of grep.
|
||||
rg combines the usability of The Silver Searcher with the raw speed of grep.
|
||||
|
||||
Common options:
|
||||
-a, --text Search binary files as if they were text.
|
||||
@@ -43,6 +50,11 @@ Common options:
|
||||
--color WHEN Whether to use coloring in match.
|
||||
Valid values are never, always or auto.
|
||||
[default: auto]
|
||||
-e, --regexp PATTERN ... Use PATTERN to search. This option can be
|
||||
provided multiple times, where all patterns
|
||||
given are searched.
|
||||
-F, --fixed-strings Treat the pattern as a literal string instead of
|
||||
a regular expression.
|
||||
-g, --glob GLOB ... Include or exclude files for searching that
|
||||
match the given glob. This always overrides any
|
||||
other ignore logic. Multiple glob flags may be
|
||||
@@ -62,6 +74,12 @@ Common options:
|
||||
to list all available types.
|
||||
-T, --type-not TYPE ... Do not search files matching TYPE. Multiple
|
||||
not-type flags may be provided.
|
||||
-u, --unrestricted ... Reduce the level of 'smart' searching. A
|
||||
single -u doesn't respect .gitignore (etc.)
|
||||
files. Two -u flags will search hidden files
|
||||
and directories. Three -u flags will search
|
||||
binary files. -uu is equivalent to grep -r,
|
||||
and -uuu is equivalent to grep -a -r.
|
||||
-v, --invert-match Invert matching.
|
||||
-w, --word-regexp Only show matches surrounded by word boundaries.
|
||||
This is equivalent to putting \\b before and
|
||||
@@ -113,13 +131,14 @@ Less common options:
|
||||
--mmap
|
||||
Search using memory maps when possible. This is enabled by default
|
||||
when ripgrep thinks it will be faster. (Note that mmap searching
|
||||
doesn't current support the various context related options.)
|
||||
doesn't currently support the various context related options.)
|
||||
|
||||
--no-mmap
|
||||
Never use memory maps, even when they might be faster.
|
||||
|
||||
--no-ignore
|
||||
Don't respect ignore files (.gitignore, .rgignore, etc.)
|
||||
This implies --no-ignore-parent.
|
||||
|
||||
--no-ignore-parent
|
||||
Don't respect ignore files in parent directories.
|
||||
@@ -127,9 +146,6 @@ Less common options:
|
||||
-p, --pretty
|
||||
Alias for --color=always --heading -n.
|
||||
|
||||
-Q, --literal
|
||||
Treat the pattern as a literal string instead of a regular expression.
|
||||
|
||||
-j, --threads ARG
|
||||
The number of threads to use. Defaults to the number of logical CPUs
|
||||
(capped at 6). [default: 0]
|
||||
@@ -171,7 +187,7 @@ pub struct RawArgs {
|
||||
flag_ignore_case: bool,
|
||||
flag_invert_match: bool,
|
||||
flag_line_number: bool,
|
||||
flag_literal: bool,
|
||||
flag_fixed_strings: bool,
|
||||
flag_mmap: bool,
|
||||
flag_no_heading: bool,
|
||||
flag_no_ignore: bool,
|
||||
@@ -180,6 +196,7 @@ pub struct RawArgs {
|
||||
flag_no_mmap: bool,
|
||||
flag_pretty: bool,
|
||||
flag_quiet: bool,
|
||||
flag_regexp: Vec<String>,
|
||||
flag_replace: Option<String>,
|
||||
flag_text: bool,
|
||||
flag_threads: usize,
|
||||
@@ -188,6 +205,7 @@ pub struct RawArgs {
|
||||
flag_type_list: bool,
|
||||
flag_type_add: Vec<String>,
|
||||
flag_type_clear: Vec<String>,
|
||||
flag_unrestricted: u32,
|
||||
flag_with_filename: bool,
|
||||
flag_word_regexp: bool,
|
||||
}
|
||||
@@ -229,19 +247,7 @@ pub struct Args {
|
||||
impl RawArgs {
|
||||
/// Convert arguments parsed into a configuration used by ripgrep.
|
||||
fn to_args(&self) -> Result<Args> {
|
||||
let pattern = {
|
||||
let pattern =
|
||||
if self.flag_literal {
|
||||
regex::quote(&self.arg_pattern)
|
||||
} else {
|
||||
self.arg_pattern.clone()
|
||||
};
|
||||
if self.flag_word_regexp {
|
||||
format!(r"\b{}\b", pattern)
|
||||
} else {
|
||||
pattern
|
||||
}
|
||||
};
|
||||
let pattern = self.pattern();
|
||||
let paths =
|
||||
if self.arg_path.is_empty() {
|
||||
if atty::on_stdin()
|
||||
@@ -267,6 +273,9 @@ impl RawArgs {
|
||||
false
|
||||
} else if self.flag_mmap {
|
||||
true
|
||||
} else if cfg!(windows) {
|
||||
// On Windows, memory maps appear faster than read calls. Neat.
|
||||
true
|
||||
} else {
|
||||
// If we're only searching a few paths and all of them are
|
||||
// files, then memory maps are probably faster.
|
||||
@@ -313,6 +322,9 @@ impl RawArgs {
|
||||
.line_terminator(eol)
|
||||
.build()
|
||||
);
|
||||
let no_ignore = self.flag_no_ignore || self.flag_unrestricted >= 1;
|
||||
let hidden = self.flag_hidden || self.flag_unrestricted >= 2;
|
||||
let text = self.flag_text || self.flag_unrestricted >= 3;
|
||||
let mut args = Args {
|
||||
pattern: pattern,
|
||||
paths: paths,
|
||||
@@ -328,16 +340,18 @@ impl RawArgs {
|
||||
glob_overrides: glob_overrides,
|
||||
grep: grep,
|
||||
heading: !self.flag_no_heading && self.flag_heading,
|
||||
hidden: self.flag_hidden,
|
||||
hidden: hidden,
|
||||
ignore_case: self.flag_ignore_case,
|
||||
invert_match: self.flag_invert_match,
|
||||
line_number: !self.flag_no_line_number && self.flag_line_number,
|
||||
mmap: mmap,
|
||||
no_ignore: self.flag_no_ignore,
|
||||
no_ignore_parent: self.flag_no_ignore_parent,
|
||||
no_ignore: no_ignore,
|
||||
no_ignore_parent:
|
||||
// --no-ignore implies --no-ignore-parent
|
||||
self.flag_no_ignore_parent || no_ignore,
|
||||
quiet: self.flag_quiet,
|
||||
replace: self.flag_replace.clone().map(|s| s.into_bytes()),
|
||||
text: self.flag_text,
|
||||
text: text,
|
||||
threads: threads,
|
||||
type_defs: btypes.definitions(),
|
||||
type_list: self.flag_type_list,
|
||||
@@ -367,10 +381,38 @@ impl RawArgs {
|
||||
types.select(ty);
|
||||
}
|
||||
for ty in &self.flag_type_not {
|
||||
types.select_not(ty);
|
||||
types.negate(ty);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pattern(&self) -> String {
|
||||
if !self.flag_regexp.is_empty() {
|
||||
if self.flag_fixed_strings {
|
||||
self.flag_regexp.iter().cloned().map(|lit| {
|
||||
self.word_pattern(regex::quote(&lit))
|
||||
}).collect::<Vec<String>>().join("|")
|
||||
} else {
|
||||
self.flag_regexp.iter().cloned().map(|pat| {
|
||||
self.word_pattern(pat)
|
||||
}).collect::<Vec<String>>().join("|")
|
||||
}
|
||||
} else {
|
||||
if self.flag_fixed_strings {
|
||||
self.word_pattern(regex::quote(&self.arg_pattern))
|
||||
} else {
|
||||
self.word_pattern(self.arg_pattern.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn word_pattern(&self, s: String) -> String {
|
||||
if self.flag_word_regexp {
|
||||
format!(r"\b{}\b", s)
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Args {
|
||||
@@ -382,9 +424,22 @@ impl Args {
|
||||
///
|
||||
/// Also, initialize a global logger.
|
||||
pub fn parse() -> Result<Args> {
|
||||
// Get all of the arguments, being careful to require valid UTF-8.
|
||||
let mut argv = vec![];
|
||||
for arg in env::args_os() {
|
||||
match arg.into_string() {
|
||||
Ok(s) => argv.push(s),
|
||||
Err(s) => {
|
||||
errored!("Argument '{}' is not valid UTF-8. \
|
||||
Use hex escape sequences to match arbitrary \
|
||||
bytes in a pattern (e.g., \\xFF).",
|
||||
s.to_string_lossy());
|
||||
}
|
||||
}
|
||||
}
|
||||
let raw: RawArgs =
|
||||
Docopt::new(USAGE)
|
||||
.and_then(|d| d.version(Some(version())).decode())
|
||||
.and_then(|d| d.argv(argv).version(Some(version())).decode())
|
||||
.unwrap_or_else(|e| e.exit());
|
||||
|
||||
let mut logb = env_logger::LogBuilder::new();
|
||||
@@ -429,7 +484,7 @@ impl Args {
|
||||
|
||||
/// Create a new printer of individual search results that writes to the
|
||||
/// writer given.
|
||||
pub fn printer<W: Send + Terminal>(&self, wtr: W) -> Printer<W> {
|
||||
pub fn printer<W: Terminal + Send>(&self, wtr: W) -> Printer<W> {
|
||||
let mut p = Printer::new(wtr)
|
||||
.column(self.column)
|
||||
.context_separator(self.context_separator.clone())
|
||||
@@ -456,8 +511,29 @@ impl Args {
|
||||
}
|
||||
|
||||
/// Create a new buffer for use with searching.
|
||||
pub fn outbuf(&self) -> OutBuffer {
|
||||
OutBuffer::new(self.color)
|
||||
#[cfg(not(windows))]
|
||||
pub fn outbuf(&self) -> ColoredTerminal<term::TerminfoTerminal<Vec<u8>>> {
|
||||
ColoredTerminal::new(vec![], self.color)
|
||||
}
|
||||
|
||||
/// Create a new buffer for use with searching.
|
||||
#[cfg(windows)]
|
||||
pub fn outbuf(&self) -> ColoredTerminal<WindowsBuffer> {
|
||||
ColoredTerminal::new_buffer(self.color)
|
||||
}
|
||||
|
||||
/// Create a new buffer for use with searching.
|
||||
#[cfg(not(windows))]
|
||||
pub fn stdout(
|
||||
&self,
|
||||
) -> ColoredTerminal<term::TerminfoTerminal<io::BufWriter<io::Stdout>>> {
|
||||
ColoredTerminal::new(io::BufWriter::new(io::stdout()), self.color)
|
||||
}
|
||||
|
||||
/// Create a new buffer for use with searching.
|
||||
#[cfg(windows)]
|
||||
pub fn stdout(&self) -> ColoredTerminal<WinConsole<io::Stdout>> {
|
||||
ColoredTerminal::new_stdout(self.color)
|
||||
}
|
||||
|
||||
/// Return the paths that should be searched.
|
||||
|
@@ -21,7 +21,7 @@ additional rules such as whitelists (prefix of `!`) or directory-only globs
|
||||
// TODO(burntsushi): Implement something similar, but for Mercurial. We can't
|
||||
// use this exact implementation because hgignore files are different.
|
||||
|
||||
use std::env;
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
@@ -31,6 +31,7 @@ use std::path::{Path, PathBuf};
|
||||
use regex;
|
||||
|
||||
use glob;
|
||||
use pathutil::strip_prefix;
|
||||
|
||||
/// Represents an error that can occur when parsing a gitignore file.
|
||||
#[derive(Debug)]
|
||||
@@ -89,21 +90,10 @@ pub struct Gitignore {
|
||||
}
|
||||
|
||||
impl Gitignore {
|
||||
/// Create a new gitignore glob matcher from the gitignore file at the
|
||||
/// given path. The root of the gitignore file is the basename of path.
|
||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Gitignore, Error> {
|
||||
let root = match path.as_ref().parent() {
|
||||
Some(parent) => parent.to_path_buf(),
|
||||
None => env::current_dir().unwrap_or(Path::new("/").to_path_buf()),
|
||||
};
|
||||
let mut builder = GitignoreBuilder::new(root);
|
||||
try!(builder.add_path(path));
|
||||
builder.build()
|
||||
}
|
||||
|
||||
/// Create a new gitignore glob matcher from the given root directory and
|
||||
/// string containing the contents of a gitignore file.
|
||||
pub fn from_str<P: AsRef<Path>>(
|
||||
#[allow(dead_code)]
|
||||
fn from_str<P: AsRef<Path>>(
|
||||
root: P,
|
||||
gitignore: &str,
|
||||
) -> Result<Gitignore, Error> {
|
||||
@@ -122,48 +112,43 @@ impl Gitignore {
|
||||
/// same directory as this gitignore file.
|
||||
pub fn matched<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match {
|
||||
let mut path = path.as_ref();
|
||||
if let Ok(p) = path.strip_prefix(&self.root) {
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
self.matched_utf8(&*path.to_string_lossy(), is_dir)
|
||||
if let Some(p) = strip_prefix(&self.root, path) {
|
||||
path = p;
|
||||
}
|
||||
self.matched_stripped(path, is_dir)
|
||||
}
|
||||
|
||||
/// Like matched, but takes a path that has already been stripped and
|
||||
/// converted to UTF-8.
|
||||
pub fn matched_utf8(&self, path: &str, is_dir: bool) -> Match {
|
||||
// A single regex with a bunch of alternations of glob patterns is
|
||||
// unfortunately typically faster than a regex, so we use it as a
|
||||
// first pass filter. We still need to run the RegexSet to get the most
|
||||
// recently defined glob that matched.
|
||||
if !self.set.is_match(path) {
|
||||
return Match::None;
|
||||
}
|
||||
// The regex set can't actually pick the right glob that matched all
|
||||
// on its own. In particular, some globs require that only directories
|
||||
// can match. Thus, only accept a match from the regex set if the given
|
||||
// path satisfies the corresponding glob's directory criteria.
|
||||
for i in self.set.matches(path).iter().rev() {
|
||||
let pat = &self.patterns[i];
|
||||
if !pat.only_dir || is_dir {
|
||||
return if pat.whitelist {
|
||||
Match::Whitelist(pat)
|
||||
} else {
|
||||
Match::Ignored(pat)
|
||||
};
|
||||
/// Like matched, but takes a path that has already been stripped.
|
||||
pub fn matched_stripped(&self, path: &Path, is_dir: bool) -> Match {
|
||||
thread_local! {
|
||||
static MATCHES: RefCell<Vec<usize>> = {
|
||||
RefCell::new(vec![])
|
||||
}
|
||||
}
|
||||
Match::None
|
||||
};
|
||||
MATCHES.with(|matches| {
|
||||
let mut matches = matches.borrow_mut();
|
||||
self.set.matches_into(path, &mut *matches);
|
||||
for &i in matches.iter().rev() {
|
||||
let pat = &self.patterns[i];
|
||||
if !pat.only_dir || is_dir {
|
||||
return if pat.whitelist {
|
||||
Match::Whitelist(pat)
|
||||
} else {
|
||||
Match::Ignored(pat)
|
||||
};
|
||||
}
|
||||
}
|
||||
Match::None
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the total number of ignore patterns.
|
||||
pub fn num_ignores(&self) -> u64 {
|
||||
self.num_ignores
|
||||
}
|
||||
|
||||
/// Returns the total number of whitelisted patterns.
|
||||
pub fn num_whitelist(&self) -> u64 {
|
||||
self.num_whitelist
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of a glob match.
|
||||
@@ -182,6 +167,7 @@ pub enum Match<'a> {
|
||||
|
||||
impl<'a> Match<'a> {
|
||||
/// Returns true if the match result implies the path should be ignored.
|
||||
#[allow(dead_code)]
|
||||
pub fn is_ignored(&self) -> bool {
|
||||
match *self {
|
||||
Match::Ignored(_) => true,
|
||||
@@ -406,6 +392,7 @@ mod tests {
|
||||
ignored!(ig23, ROOT, "foo", "./foo");
|
||||
ignored!(ig24, ROOT, "target", "grep/target");
|
||||
ignored!(ig25, ROOT, "Cargo.lock", "./tabwriter-bin/Cargo.lock");
|
||||
ignored!(ig26, ROOT, "/foo/bar/baz", "./foo/bar/baz");
|
||||
|
||||
not_ignored!(ignot1, ROOT, "amonths", "months");
|
||||
not_ignored!(ignot2, ROOT, "monthsa", "months");
|
||||
|
458
src/glob.rs
458
src/glob.rs
@@ -26,13 +26,22 @@ to make its way into `glob` proper.
|
||||
// at the .gitignore for the chromium repo---just about every pattern satisfies
|
||||
// that assumption.)
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error as StdError;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fmt;
|
||||
use std::hash;
|
||||
use std::iter;
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
|
||||
use fnv;
|
||||
use regex;
|
||||
use regex::bytes::{Regex, RegexSet, SetMatches};
|
||||
use regex::bytes::Regex;
|
||||
use regex::bytes::RegexSet;
|
||||
|
||||
use pathutil::file_name;
|
||||
|
||||
/// Represents an error that can occur when parsing a glob pattern.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@@ -71,32 +80,181 @@ impl fmt::Display for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// SetYesNo represents a group of globs that can be matched together in a
|
||||
/// single pass. SetYesNo can only determine whether a particular path matched
|
||||
/// any pattern in the set.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SetYesNo {
|
||||
re: Regex,
|
||||
}
|
||||
|
||||
impl SetYesNo {
|
||||
/// Returns true if and only if the given path matches at least one glob
|
||||
/// in this set.
|
||||
pub fn is_match<T: AsRef<Path>>(&self, path: T) -> bool {
|
||||
self.re.is_match(&*path_bytes(path.as_ref()))
|
||||
}
|
||||
|
||||
fn new(
|
||||
pats: &[(Pattern, MatchOptions)],
|
||||
) -> Result<SetYesNo, regex::Error> {
|
||||
let mut joined = String::new();
|
||||
for &(ref p, ref o) in pats {
|
||||
let part = format!("(?:{})", p.to_regex_with(o));
|
||||
if !joined.is_empty() {
|
||||
joined.push('|');
|
||||
}
|
||||
joined.push_str(&part);
|
||||
}
|
||||
Ok(SetYesNo { re: try!(Regex::new(&joined)) })
|
||||
}
|
||||
}
|
||||
|
||||
type Fnv = hash::BuildHasherDefault<fnv::FnvHasher>;
|
||||
|
||||
/// Set represents a group of globs that can be matched together in a single
|
||||
/// pass.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Set {
|
||||
re: Regex,
|
||||
set: RegexSet,
|
||||
yesno: SetYesNo,
|
||||
exts: HashMap<OsString, Vec<usize>, Fnv>,
|
||||
literals: HashMap<Vec<u8>, Vec<usize>, Fnv>,
|
||||
base_literals: HashMap<Vec<u8>, Vec<usize>, Fnv>,
|
||||
base_prefixes: Vec<Vec<u8>>,
|
||||
base_prefixes_map: Vec<usize>,
|
||||
base_suffixes: Vec<Vec<u8>>,
|
||||
base_suffixes_map: Vec<usize>,
|
||||
base_regexes: RegexSet,
|
||||
base_regexes_map: Vec<usize>,
|
||||
regexes: RegexSet,
|
||||
regexes_map: Vec<usize>,
|
||||
}
|
||||
|
||||
impl Set {
|
||||
/// Returns true if and only if the given path matches at least one glob
|
||||
/// in this set.
|
||||
pub fn is_match<T: AsRef<[u8]>>(&self, path: T) -> bool {
|
||||
self.re.is_match(path.as_ref())
|
||||
/// Returns the sequence number of every glob pattern that matches the
|
||||
/// given path.
|
||||
#[allow(dead_code)]
|
||||
pub fn matches<T: AsRef<Path>>(&self, path: T) -> Vec<usize> {
|
||||
let mut into = vec![];
|
||||
self.matches_into(path, &mut into);
|
||||
into
|
||||
}
|
||||
|
||||
/// Returns every glob pattern (by sequence number) that matches the given
|
||||
/// path.
|
||||
pub fn matches<T: AsRef<[u8]>>(&self, path: T) -> SetMatches {
|
||||
// TODO(burntsushi): If we split this out into a separate crate, don't
|
||||
// expose the regex::SetMatches type in the public API.
|
||||
self.set.matches(path.as_ref())
|
||||
/// Adds the sequence number of every glob pattern that matches the given
|
||||
/// path to the vec given.
|
||||
pub fn matches_into<T: AsRef<Path>>(
|
||||
&self,
|
||||
path: T,
|
||||
into: &mut Vec<usize>,
|
||||
) {
|
||||
into.clear();
|
||||
let path = path.as_ref();
|
||||
let path_bytes = &*path_bytes(path);
|
||||
let basename = file_name(path).map(|b| os_str_bytes(b));
|
||||
if !self.yesno.is_match(path) {
|
||||
return;
|
||||
}
|
||||
if !self.exts.is_empty() {
|
||||
if let Some(ext) = path.extension() {
|
||||
if let Some(matches) = self.exts.get(ext) {
|
||||
into.extend(matches.as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.literals.is_empty() {
|
||||
if let Some(matches) = self.literals.get(path_bytes) {
|
||||
into.extend(matches.as_slice());
|
||||
}
|
||||
}
|
||||
if !self.base_literals.is_empty() {
|
||||
if let Some(ref basename) = basename {
|
||||
if let Some(matches) = self.base_literals.get(&**basename) {
|
||||
into.extend(matches.as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.base_prefixes.is_empty() {
|
||||
if let Some(ref basename) = basename {
|
||||
let basename = &**basename;
|
||||
for (i, pre) in self.base_prefixes.iter().enumerate() {
|
||||
if pre.len() <= basename.len() && &**pre == &basename[0..pre.len()] {
|
||||
into.push(self.base_prefixes_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.base_suffixes.is_empty() {
|
||||
if let Some(ref basename) = basename {
|
||||
let basename = &**basename;
|
||||
for (i, suf) in self.base_suffixes.iter().enumerate() {
|
||||
if suf.len() > basename.len() {
|
||||
continue;
|
||||
}
|
||||
let (s, e) = (basename.len() - suf.len(), basename.len());
|
||||
if &**suf == &basename[s..e] {
|
||||
into.push(self.base_suffixes_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref basename) = basename {
|
||||
for i in self.base_regexes.matches(&**basename) {
|
||||
into.push(self.base_regexes_map[i]);
|
||||
}
|
||||
}
|
||||
for i in self.regexes.matches(path_bytes) {
|
||||
into.push(self.regexes_map[i]);
|
||||
}
|
||||
into.sort();
|
||||
}
|
||||
|
||||
/// Returns the number of glob patterns in this set.
|
||||
pub fn len(&self) -> usize {
|
||||
self.set.len()
|
||||
fn new(pats: &[(Pattern, MatchOptions)]) -> Result<Set, regex::Error> {
|
||||
let fnv = Fnv::default();
|
||||
let mut exts = HashMap::with_hasher(fnv.clone());
|
||||
let mut literals = HashMap::with_hasher(fnv.clone());
|
||||
let mut base_literals = HashMap::with_hasher(fnv.clone());
|
||||
let (mut base_prefixes, mut base_prefixes_map) = (vec![], vec![]);
|
||||
let (mut base_suffixes, mut base_suffixes_map) = (vec![], vec![]);
|
||||
let (mut regexes, mut regexes_map) = (vec![], vec![]);
|
||||
let (mut base_regexes, mut base_regexes_map) = (vec![], vec![]);
|
||||
for (i, &(ref p, ref o)) in pats.iter().enumerate() {
|
||||
if let Some(ext) = p.ext() {
|
||||
exts.entry(ext).or_insert(vec![]).push(i);
|
||||
} else if let Some(literal) = p.literal() {
|
||||
literals.entry(literal.into_bytes()).or_insert(vec![]).push(i);
|
||||
} else if let Some(literal) = p.base_literal() {
|
||||
base_literals
|
||||
.entry(literal.into_bytes()).or_insert(vec![]).push(i);
|
||||
} else if let Some(literal) = p.base_literal_prefix() {
|
||||
base_prefixes.push(literal.into_bytes());
|
||||
base_prefixes_map.push(i);
|
||||
} else if let Some(literal) = p.base_literal_suffix() {
|
||||
base_suffixes.push(literal.into_bytes());
|
||||
base_suffixes_map.push(i);
|
||||
} else if p.is_only_basename() {
|
||||
let part = format!("(?:{})", p.to_regex_with(o));
|
||||
base_regexes.push(part);
|
||||
base_regexes_map.push(i);
|
||||
} else {
|
||||
let part = format!("(?:{})", p.to_regex_with(o));
|
||||
regexes.push(part);
|
||||
regexes_map.push(i);
|
||||
}
|
||||
}
|
||||
Ok(Set {
|
||||
yesno: try!(SetYesNo::new(pats)),
|
||||
exts: exts,
|
||||
literals: literals,
|
||||
base_literals: base_literals,
|
||||
base_prefixes: base_prefixes,
|
||||
base_prefixes_map: base_prefixes_map,
|
||||
base_suffixes: base_suffixes,
|
||||
base_suffixes_map: base_suffixes_map,
|
||||
base_regexes: try!(RegexSet::new(base_regexes)),
|
||||
base_regexes_map: base_regexes_map,
|
||||
regexes: try!(RegexSet::new(regexes)),
|
||||
regexes_map: regexes_map,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,25 +276,19 @@ impl SetBuilder {
|
||||
///
|
||||
/// Once a matcher is built, no new patterns can be added to it.
|
||||
pub fn build(&self) -> Result<Set, regex::Error> {
|
||||
let it = self.pats.iter().map(|&(ref p, ref o)| p.to_regex_with(o));
|
||||
let set = try!(RegexSet::new(it));
|
||||
Set::new(&self.pats)
|
||||
}
|
||||
|
||||
let mut joined = String::new();
|
||||
for &(ref p, ref o) in &self.pats {
|
||||
let part = format!("(?:{})", p.to_regex_with(o));
|
||||
if !joined.is_empty() {
|
||||
joined.push('|');
|
||||
}
|
||||
joined.push_str(&part);
|
||||
}
|
||||
let re = try!(Regex::new(&joined));
|
||||
Ok(Set { re: re, set: set })
|
||||
/// Like `build`, but returns a matcher that can only answer yes/no.
|
||||
pub fn build_yesno(&self) -> Result<SetYesNo, regex::Error> {
|
||||
SetYesNo::new(&self.pats)
|
||||
}
|
||||
|
||||
/// Add a new pattern to this set.
|
||||
///
|
||||
/// If the pattern could not be parsed as a glob, then an error is
|
||||
/// returned.
|
||||
#[allow(dead_code)]
|
||||
pub fn add(&mut self, pat: &str) -> Result<(), Error> {
|
||||
self.add_with(pat, &MatchOptions::default())
|
||||
}
|
||||
@@ -147,8 +299,21 @@ impl SetBuilder {
|
||||
pat: &str,
|
||||
opts: &MatchOptions,
|
||||
) -> Result<(), Error> {
|
||||
let pat = try!(Pattern::new(pat));
|
||||
self.pats.push((pat, opts.clone()));
|
||||
let parsed = try!(Pattern::new(pat));
|
||||
// if let Some(ext) = parsed.ext() {
|
||||
// eprintln!("ext :: {:?} :: {:?}", ext, pat);
|
||||
// } else if let Some(lit) = parsed.literal() {
|
||||
// eprintln!("literal :: {:?} :: {:?}", lit, pat);
|
||||
// } else if let Some(lit) = parsed.base_literal() {
|
||||
// eprintln!("base_literal :: {:?} :: {:?}", lit, pat);
|
||||
// } else if let Some(lit) = parsed.base_literal_prefix() {
|
||||
// eprintln!("base_literal :: {:?} :: {:?}", lit, pat);
|
||||
// } else if let Some(lit) = parsed.base_literal_suffix() {
|
||||
// eprintln!("base_literal :: {:?} :: {:?}", lit, pat);
|
||||
// } else {
|
||||
// eprintln!("regex :: {:?} :: {:?}", pat, parsed);
|
||||
// }
|
||||
self.pats.push((parsed, opts.clone()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -202,9 +367,137 @@ impl Pattern {
|
||||
Ok(p.p)
|
||||
}
|
||||
|
||||
/// Returns an extension if this pattern exclusively matches it.
|
||||
pub fn ext(&self) -> Option<OsString> {
|
||||
if self.tokens.len() <= 3 {
|
||||
return None;
|
||||
}
|
||||
match self.tokens.get(0) {
|
||||
Some(&Token::RecursivePrefix) => {}
|
||||
_ => return None,
|
||||
}
|
||||
match self.tokens.get(1) {
|
||||
Some(&Token::ZeroOrMore) => {}
|
||||
_ => return None,
|
||||
}
|
||||
match self.tokens.get(2) {
|
||||
Some(&Token::Literal(c)) if c == '.' => {}
|
||||
_ => return None,
|
||||
}
|
||||
let mut lit = OsString::new();
|
||||
for t in self.tokens[3..].iter() {
|
||||
match *t {
|
||||
Token::Literal(c) if c == '/' || c == '\\' || c == '.' => {
|
||||
return None;
|
||||
}
|
||||
Token::Literal(c) => lit.push(c.to_string()),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
Some(lit)
|
||||
}
|
||||
|
||||
/// Returns the pattern as a literal if and only if the pattern exclusiely
|
||||
/// matches the basename of a file path *and* is a literal.
|
||||
///
|
||||
/// The basic format of these patterns is `**/{literal}`, where `{literal}`
|
||||
/// does not contain a path separator.
|
||||
pub fn base_literal(&self) -> Option<String> {
|
||||
match self.tokens.get(0) {
|
||||
Some(&Token::RecursivePrefix) => {}
|
||||
_ => return None,
|
||||
}
|
||||
let mut lit = String::new();
|
||||
for t in &self.tokens[1..] {
|
||||
match *t {
|
||||
Token::Literal(c) if c == '/' || c == '\\' => return None,
|
||||
Token::Literal(c) => lit.push(c),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
Some(lit)
|
||||
}
|
||||
|
||||
/// Returns true if and only if this pattern only inspects the basename
|
||||
/// of a path.
|
||||
pub fn is_only_basename(&self) -> bool {
|
||||
match self.tokens.get(0) {
|
||||
Some(&Token::RecursivePrefix) => {}
|
||||
_ => return false,
|
||||
}
|
||||
for t in &self.tokens[1..] {
|
||||
match *t {
|
||||
Token::Literal(c) if c == '/' || c == '\\' => return false,
|
||||
Token::RecursivePrefix
|
||||
| Token::RecursiveSuffix
|
||||
| Token::RecursiveZeroOrMore => return false,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns the pattern as a literal if and only if the pattern must match
|
||||
/// an entire path exactly.
|
||||
///
|
||||
/// The basic format of these patterns is `{literal}`.
|
||||
pub fn literal(&self) -> Option<String> {
|
||||
let mut lit = String::new();
|
||||
for t in &self.tokens {
|
||||
match *t {
|
||||
Token::Literal(c) => lit.push(c),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
Some(lit)
|
||||
}
|
||||
|
||||
/// Returns a basename literal prefix of this pattern.
|
||||
pub fn base_literal_prefix(&self) -> Option<String> {
|
||||
match self.tokens.get(0) {
|
||||
Some(&Token::RecursivePrefix) => {}
|
||||
_ => return None,
|
||||
}
|
||||
match self.tokens.last() {
|
||||
Some(&Token::ZeroOrMore) => {}
|
||||
_ => return None,
|
||||
}
|
||||
let mut lit = String::new();
|
||||
for t in &self.tokens[1..self.tokens.len()-1] {
|
||||
match *t {
|
||||
Token::Literal(c) if c == '/' || c == '\\' => return None,
|
||||
Token::Literal(c) => lit.push(c),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
Some(lit)
|
||||
}
|
||||
|
||||
/// Returns a basename literal suffix of this pattern.
|
||||
pub fn base_literal_suffix(&self) -> Option<String> {
|
||||
match self.tokens.get(0) {
|
||||
Some(&Token::RecursivePrefix) => {}
|
||||
_ => return None,
|
||||
}
|
||||
match self.tokens.get(1) {
|
||||
Some(&Token::ZeroOrMore) => {}
|
||||
_ => return None,
|
||||
}
|
||||
let mut lit = String::new();
|
||||
for t in &self.tokens[2..] {
|
||||
match *t {
|
||||
Token::Literal(c) if c == '/' || c == '\\' => return None,
|
||||
Token::Literal(c) => lit.push(c),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
Some(lit)
|
||||
}
|
||||
|
||||
/// Convert this pattern to a string that is guaranteed to be a valid
|
||||
/// regular expression and will represent the matching semantics of this
|
||||
/// glob pattern. This uses a default set of options.
|
||||
#[allow(dead_code)]
|
||||
pub fn to_regex(&self) -> String {
|
||||
self.to_regex_with(&MatchOptions::default())
|
||||
}
|
||||
@@ -315,7 +608,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
let last = self.p.tokens.pop().unwrap();
|
||||
self.p.tokens.pop().unwrap();
|
||||
if prev != Some('/') {
|
||||
return Err(Error::InvalidRecursive);
|
||||
}
|
||||
@@ -412,13 +705,34 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn path_bytes(path: &Path) -> Cow<[u8]> {
|
||||
os_str_bytes(path.as_os_str())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn os_str_bytes(s: &OsStr) -> Cow<[u8]> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
Cow::Borrowed(s.as_bytes())
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn os_str_bytes(s: &OsStr) -> Cow<[u8]> {
|
||||
// TODO(burntsushi): On Windows, OS strings are probably UTF-16, so even
|
||||
// if we could get at the raw bytes, they wouldn't be useful. We *must*
|
||||
// convert to UTF-8 before doing path matching. Unfortunate, but necessary.
|
||||
match s.to_string_lossy() {
|
||||
Cow::Owned(s) => Cow::Owned(s.into_bytes()),
|
||||
Cow::Borrowed(s) => Cow::Borrowed(s.as_bytes()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use regex::bytes::Regex;
|
||||
|
||||
use super::{Error, Pattern, MatchOptions, SetBuilder, Token};
|
||||
use super::{Error, Pattern, MatchOptions, Set, SetBuilder, Token};
|
||||
use super::Token::*;
|
||||
|
||||
macro_rules! syntax {
|
||||
@@ -480,14 +794,42 @@ mod tests {
|
||||
let pat = Pattern::new($pat).unwrap();
|
||||
let path = &Path::new($path).to_str().unwrap();
|
||||
let re = Regex::new(&pat.to_regex_with(&$options)).unwrap();
|
||||
// println!("PATTERN: {}", $pat);
|
||||
// println!("REGEX: {:?}", re);
|
||||
// println!("PATH: {}", path);
|
||||
assert!(!re.is_match(path.as_bytes()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! ext {
|
||||
($name:ident, $pat:expr, $ext:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let pat = Pattern::new($pat).unwrap();
|
||||
let ext = pat.ext().map(|e| e.to_string_lossy().into_owned());
|
||||
assert_eq!($ext, ext.as_ref().map(|s| &**s));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! baseliteral {
|
||||
($name:ident, $pat:expr, $yes:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let pat = Pattern::new($pat).unwrap();
|
||||
assert_eq!($yes, pat.base_literal().is_some());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! basesuffix {
|
||||
($name:ident, $pat:expr, $yes:expr) => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let pat = Pattern::new($pat).unwrap();
|
||||
assert_eq!($yes, pat.is_literal_suffix());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn class(s: char, e: char) -> Token {
|
||||
Class { negated: false, ranges: vec![(s, e)] }
|
||||
}
|
||||
@@ -582,6 +924,26 @@ mod tests {
|
||||
toregex!(re10, "+", r"^\+$");
|
||||
toregex!(re11, "**", r"^.*$");
|
||||
|
||||
ext!(ext1, "**/*.rs", Some("rs"));
|
||||
|
||||
baseliteral!(lit1, "**", true);
|
||||
baseliteral!(lit2, "**/a", true);
|
||||
baseliteral!(lit3, "**/ab", true);
|
||||
baseliteral!(lit4, "**/a*b", false);
|
||||
baseliteral!(lit5, "z/**/a*b", false);
|
||||
baseliteral!(lit6, "[ab]", false);
|
||||
baseliteral!(lit7, "?", false);
|
||||
|
||||
/*
|
||||
issuffix!(suf1, "", false);
|
||||
issuffix!(suf2, "a", true);
|
||||
issuffix!(suf3, "ab", true);
|
||||
issuffix!(suf4, "*ab", true);
|
||||
issuffix!(suf5, "*.ab", true);
|
||||
issuffix!(suf6, "?.ab", true);
|
||||
issuffix!(suf7, "ab*", false);
|
||||
*/
|
||||
|
||||
matches!(match1, "a", "a");
|
||||
matches!(match2, "a*b", "a_b");
|
||||
matches!(match3, "a*b*c", "abc");
|
||||
@@ -678,16 +1040,22 @@ mod tests {
|
||||
builder.add("src/lib.rs").unwrap();
|
||||
let set = builder.build().unwrap();
|
||||
|
||||
assert!(set.is_match("foo.c"));
|
||||
assert!(set.is_match("src/foo.c"));
|
||||
assert!(!set.is_match("foo.rs"));
|
||||
assert!(!set.is_match("tests/foo.rs"));
|
||||
assert!(set.is_match("src/foo.rs"));
|
||||
assert!(set.is_match("src/grep/src/main.rs"));
|
||||
fn is_match(set: &Set, s: &str) -> bool {
|
||||
let mut matches = vec![];
|
||||
set.matches_into(s, &mut matches);
|
||||
!matches.is_empty()
|
||||
}
|
||||
|
||||
assert_eq!(2, set.matches("src/lib.rs").iter().count());
|
||||
assert!(set.matches("src/lib.rs").matched(0));
|
||||
assert!(!set.matches("src/lib.rs").matched(1));
|
||||
assert!(set.matches("src/lib.rs").matched(2));
|
||||
assert!(is_match(&set, "foo.c"));
|
||||
assert!(is_match(&set, "src/foo.c"));
|
||||
assert!(!is_match(&set, "foo.rs"));
|
||||
assert!(!is_match(&set, "tests/foo.rs"));
|
||||
assert!(is_match(&set, "src/foo.rs"));
|
||||
assert!(is_match(&set, "src/grep/src/main.rs"));
|
||||
|
||||
let matches = set.matches("src/lib.rs");
|
||||
assert_eq!(2, matches.len());
|
||||
assert_eq!(0, matches[0]);
|
||||
assert_eq!(2, matches[1]);
|
||||
}
|
||||
}
|
||||
|
@@ -19,11 +19,11 @@ use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use gitignore::{self, Gitignore, GitignoreBuilder, Match, Pattern};
|
||||
use pathutil::is_hidden;
|
||||
use types::Types;
|
||||
|
||||
const IGNORE_NAMES: &'static [&'static str] = &[
|
||||
".gitignore",
|
||||
".agignore",
|
||||
".rgignore",
|
||||
];
|
||||
|
||||
@@ -83,7 +83,10 @@ pub struct Ignore {
|
||||
overrides: Overrides,
|
||||
/// A file type matcher.
|
||||
types: Types,
|
||||
/// Whether to ignore hidden files or not.
|
||||
ignore_hidden: bool,
|
||||
/// When true, don't look at .gitignore or .agignore files for ignore
|
||||
/// rules.
|
||||
no_ignore: bool,
|
||||
}
|
||||
|
||||
@@ -208,15 +211,17 @@ impl Ignore {
|
||||
debug!("{} ignored because it is hidden", path.display());
|
||||
return true;
|
||||
}
|
||||
for id in self.stack.iter().rev().filter_map(|id| id.as_ref()) {
|
||||
let mat = id.matched(path, is_dir);
|
||||
if let Some(is_ignored) = self.ignore_match(path, mat) {
|
||||
if is_ignored {
|
||||
return true;
|
||||
if !self.no_ignore {
|
||||
for id in self.stack.iter().rev().filter_map(|id| id.as_ref()) {
|
||||
let mat = id.matched(path, is_dir);
|
||||
if let Some(is_ignored) = self.ignore_match(path, mat) {
|
||||
if is_ignored {
|
||||
return true;
|
||||
}
|
||||
// If this path is whitelisted by an ignore, then
|
||||
// fallthrough and let the file type matcher have a say.
|
||||
break;
|
||||
}
|
||||
// If this path is whitelisted by an ignore, then fallthrough
|
||||
// and let the file type matcher have a say.
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mat = self.types.matched(path, is_dir);
|
||||
@@ -361,8 +366,7 @@ impl Overrides {
|
||||
let path = path.as_ref();
|
||||
self.gi.as_ref()
|
||||
.map(|gi| {
|
||||
let path = &*path.to_string_lossy();
|
||||
let mat = gi.matched_utf8(path, is_dir).invert();
|
||||
let mat = gi.matched_stripped(path, is_dir).invert();
|
||||
if mat.is_none() && !is_dir {
|
||||
if gi.num_ignores() > 0 {
|
||||
return Match::Ignored(&self.unmatched_pat);
|
||||
@@ -374,14 +378,6 @@ impl Overrides {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
if let Some(name) = path.as_ref().file_name() {
|
||||
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
151
src/main.rs
151
src/main.rs
@@ -1,8 +1,7 @@
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
extern crate crossbeam;
|
||||
extern crate deque;
|
||||
extern crate docopt;
|
||||
extern crate env_logger;
|
||||
extern crate fnv;
|
||||
extern crate grep;
|
||||
#[cfg(windows)]
|
||||
extern crate kernel32;
|
||||
@@ -15,10 +14,8 @@ extern crate memchr;
|
||||
extern crate memmap;
|
||||
extern crate num_cpus;
|
||||
extern crate regex;
|
||||
extern crate regex_syntax as syntax;
|
||||
extern crate rustc_serialize;
|
||||
extern crate term;
|
||||
extern crate thread_local;
|
||||
extern crate walkdir;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
@@ -26,22 +23,25 @@ extern crate winapi;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process;
|
||||
use std::result;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
use crossbeam::sync::chase_lev::{self, Steal, Stealer};
|
||||
use deque::{Stealer, Stolen};
|
||||
use grep::Grep;
|
||||
use memmap::{Mmap, Protection};
|
||||
use term::Terminal;
|
||||
use walkdir::DirEntry;
|
||||
|
||||
use args::Args;
|
||||
use out::{NoColorTerminal, Out, OutBuffer};
|
||||
use out::{ColoredTerminal, Out};
|
||||
use pathutil::strip_prefix;
|
||||
use printer::Printer;
|
||||
use search_stream::InputBuffer;
|
||||
#[cfg(windows)]
|
||||
use terminal_win::WindowsBuffer;
|
||||
|
||||
macro_rules! errored {
|
||||
($($tt:tt)*) => {
|
||||
@@ -62,10 +62,12 @@ mod gitignore;
|
||||
mod glob;
|
||||
mod ignore;
|
||||
mod out;
|
||||
mod pathutil;
|
||||
mod printer;
|
||||
mod search_buffer;
|
||||
mod search_stream;
|
||||
mod terminal;
|
||||
#[cfg(windows)]
|
||||
mod terminal_win;
|
||||
mod types;
|
||||
mod walk;
|
||||
|
||||
@@ -74,7 +76,7 @@ pub type Result<T> = result::Result<T, Box<Error + Send + Sync>>;
|
||||
fn main() {
|
||||
match Args::parse().and_then(run) {
|
||||
Ok(count) if count == 0 => process::exit(1),
|
||||
Ok(count) => process::exit(0),
|
||||
Ok(_) => process::exit(0),
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
process::exit(1);
|
||||
@@ -83,42 +85,56 @@ fn main() {
|
||||
}
|
||||
|
||||
fn run(args: Args) -> Result<u64> {
|
||||
let args = Arc::new(args);
|
||||
let paths = args.paths();
|
||||
if args.files() {
|
||||
return run_files(args);
|
||||
return run_files(args.clone());
|
||||
}
|
||||
if args.type_list() {
|
||||
return run_types(args);
|
||||
return run_types(args.clone());
|
||||
}
|
||||
let args = Arc::new(args);
|
||||
if paths.len() == 1 && (paths[0] == Path::new("-") || paths[0].is_file()) {
|
||||
return run_one(args.clone(), &paths[0]);
|
||||
}
|
||||
|
||||
let out = Arc::new(Mutex::new(args.out()));
|
||||
let outbuf = args.outbuf();
|
||||
let mut workers = vec![];
|
||||
|
||||
let mut workq = {
|
||||
let (workq, stealer) = chase_lev::deque();
|
||||
let workq = {
|
||||
let (workq, stealer) = deque::new();
|
||||
for _ in 0..args.threads() {
|
||||
let worker = Worker {
|
||||
args: args.clone(),
|
||||
out: out.clone(),
|
||||
let worker = MultiWorker {
|
||||
chan_work: stealer.clone(),
|
||||
inpbuf: args.input_buffer(),
|
||||
outbuf: Some(outbuf.clone()),
|
||||
grep: args.grep(),
|
||||
match_count: 0,
|
||||
out: out.clone(),
|
||||
outbuf: Some(args.outbuf()),
|
||||
worker: Worker {
|
||||
args: args.clone(),
|
||||
inpbuf: args.input_buffer(),
|
||||
grep: args.grep(),
|
||||
match_count: 0,
|
||||
},
|
||||
};
|
||||
workers.push(thread::spawn(move || worker.run()));
|
||||
}
|
||||
workq
|
||||
};
|
||||
for p in args.paths() {
|
||||
let mut paths_searched: u64 = 0;
|
||||
for p in paths {
|
||||
if p == Path::new("-") {
|
||||
workq.push(Work::Stdin)
|
||||
paths_searched += 1;
|
||||
workq.push(Work::Stdin);
|
||||
} else {
|
||||
for ent in try!(args.walker(p)) {
|
||||
paths_searched += 1;
|
||||
workq.push(Work::File(ent));
|
||||
}
|
||||
}
|
||||
}
|
||||
if !paths.is_empty() && paths_searched == 0 {
|
||||
eprintln!("No files were searched, which means ripgrep probably \
|
||||
applied a filter you didn't expect. \
|
||||
Try running again with --debug.");
|
||||
}
|
||||
for _ in 0..workers.len() {
|
||||
workq.push(Work::Quit);
|
||||
}
|
||||
@@ -129,8 +145,27 @@ fn run(args: Args) -> Result<u64> {
|
||||
Ok(match_count)
|
||||
}
|
||||
|
||||
fn run_files(args: Args) -> Result<u64> {
|
||||
let term = NoColorTerminal::new(io::BufWriter::new(io::stdout()));
|
||||
fn run_one(args: Arc<Args>, path: &Path) -> Result<u64> {
|
||||
let mut worker = Worker {
|
||||
args: args.clone(),
|
||||
inpbuf: args.input_buffer(),
|
||||
grep: args.grep(),
|
||||
match_count: 0,
|
||||
};
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
let work =
|
||||
if path == Path::new("-") {
|
||||
WorkReady::Stdin
|
||||
} else {
|
||||
WorkReady::PathFile(path.to_path_buf(), try!(File::open(path)))
|
||||
};
|
||||
worker.do_work(&mut printer, work);
|
||||
Ok(worker.match_count)
|
||||
}
|
||||
|
||||
fn run_files(args: Arc<Args>) -> Result<u64> {
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
let mut file_count = 0;
|
||||
for p in args.paths() {
|
||||
@@ -147,8 +182,8 @@ fn run_files(args: Args) -> Result<u64> {
|
||||
Ok(file_count)
|
||||
}
|
||||
|
||||
fn run_types(args: Args) -> Result<u64> {
|
||||
let term = NoColorTerminal::new(io::BufWriter::new(io::stdout()));
|
||||
fn run_types(args: Arc<Args>) -> Result<u64> {
|
||||
let term = args.stdout();
|
||||
let mut printer = args.printer(term);
|
||||
let mut ty_count = 0;
|
||||
for def in args.type_defs() {
|
||||
@@ -166,30 +201,37 @@ enum Work {
|
||||
|
||||
enum WorkReady {
|
||||
Stdin,
|
||||
File(DirEntry, File),
|
||||
DirFile(DirEntry, File),
|
||||
PathFile(PathBuf, File),
|
||||
}
|
||||
|
||||
struct MultiWorker {
|
||||
chan_work: Stealer<Work>,
|
||||
out: Arc<Mutex<Out>>,
|
||||
#[cfg(not(windows))]
|
||||
outbuf: Option<ColoredTerminal<term::TerminfoTerminal<Vec<u8>>>>,
|
||||
#[cfg(windows)]
|
||||
outbuf: Option<ColoredTerminal<WindowsBuffer>>,
|
||||
worker: Worker,
|
||||
}
|
||||
|
||||
struct Worker {
|
||||
args: Arc<Args>,
|
||||
out: Arc<Mutex<Out>>,
|
||||
chan_work: Stealer<Work>,
|
||||
inpbuf: InputBuffer,
|
||||
outbuf: Option<OutBuffer>,
|
||||
grep: Grep,
|
||||
match_count: u64,
|
||||
}
|
||||
|
||||
impl Worker {
|
||||
impl MultiWorker {
|
||||
fn run(mut self) -> u64 {
|
||||
self.match_count = 0;
|
||||
loop {
|
||||
let work = match self.chan_work.steal() {
|
||||
Steal::Empty | Steal::Abort => continue,
|
||||
Steal::Data(Work::Quit) => break,
|
||||
Steal::Data(Work::Stdin) => WorkReady::Stdin,
|
||||
Steal::Data(Work::File(ent)) => {
|
||||
Stolen::Empty | Stolen::Abort => continue,
|
||||
Stolen::Data(Work::Quit) => break,
|
||||
Stolen::Data(Work::Stdin) => WorkReady::Stdin,
|
||||
Stolen::Data(Work::File(ent)) => {
|
||||
match File::open(ent.path()) {
|
||||
Ok(file) => WorkReady::File(ent, file),
|
||||
Ok(file) => WorkReady::DirFile(ent, file),
|
||||
Err(err) => {
|
||||
eprintln!("{}: {}", ent.path().display(), err);
|
||||
continue;
|
||||
@@ -199,8 +241,8 @@ impl Worker {
|
||||
};
|
||||
let mut outbuf = self.outbuf.take().unwrap();
|
||||
outbuf.clear();
|
||||
let mut printer = self.args.printer(outbuf);
|
||||
self.do_work(&mut printer, work);
|
||||
let mut printer = self.worker.args.printer(outbuf);
|
||||
self.worker.do_work(&mut printer, work);
|
||||
let outbuf = printer.into_inner();
|
||||
if !outbuf.get_ref().is_empty() {
|
||||
let mut out = self.out.lock().unwrap();
|
||||
@@ -208,10 +250,12 @@ impl Worker {
|
||||
}
|
||||
self.outbuf = Some(outbuf);
|
||||
}
|
||||
self.match_count
|
||||
self.worker.match_count
|
||||
}
|
||||
}
|
||||
|
||||
fn do_work<W: Send + Terminal>(
|
||||
impl Worker {
|
||||
fn do_work<W: Terminal + Send>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
work: WorkReady,
|
||||
@@ -222,9 +266,20 @@ impl Worker {
|
||||
let stdin = stdin.lock();
|
||||
self.search(printer, &Path::new("<stdin>"), stdin)
|
||||
}
|
||||
WorkReady::File(ent, file) => {
|
||||
WorkReady::DirFile(ent, file) => {
|
||||
let mut path = ent.path();
|
||||
if let Ok(p) = path.strip_prefix("./") {
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
if self.args.mmap() {
|
||||
self.search_mmap(printer, path, &file)
|
||||
} else {
|
||||
self.search(printer, path, file)
|
||||
}
|
||||
}
|
||||
WorkReady::PathFile(path, file) => {
|
||||
let mut path = &*path;
|
||||
if let Some(p) = strip_prefix("./", path) {
|
||||
path = p;
|
||||
}
|
||||
if self.args.mmap() {
|
||||
@@ -244,7 +299,7 @@ impl Worker {
|
||||
}
|
||||
}
|
||||
|
||||
fn search<R: io::Read, W: Send + Terminal>(
|
||||
fn search<R: io::Read, W: Terminal + Send>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
path: &Path,
|
||||
@@ -259,7 +314,7 @@ impl Worker {
|
||||
).run().map_err(From::from)
|
||||
}
|
||||
|
||||
fn search_mmap<W: Send + Terminal>(
|
||||
fn search_mmap<W: Terminal + Send>(
|
||||
&mut self,
|
||||
printer: &mut Printer<W>,
|
||||
path: &Path,
|
||||
|
524
src/out.rs
524
src/out.rs
@@ -1,40 +1,13 @@
|
||||
use std::io::{self, Write};
|
||||
use std::sync::Arc;
|
||||
|
||||
use term::{self, Terminal};
|
||||
use term::color::Color;
|
||||
#[cfg(not(windows))]
|
||||
use term::terminfo::TermInfo;
|
||||
#[cfg(windows)]
|
||||
use term::WinConsole;
|
||||
|
||||
use terminal::TerminfoTerminal;
|
||||
|
||||
pub type StdoutTerminal = Box<Terminal<Output=io::Stdout> + Send>;
|
||||
|
||||
/// Gets a terminal that supports color if available.
|
||||
#[cfg(windows)]
|
||||
fn term_stdout(color: bool) -> StdoutTerminal {
|
||||
let stdout = io::stdout();
|
||||
WinConsole::new(stdout)
|
||||
.ok()
|
||||
.map(|t| Box::new(t) as StdoutTerminal)
|
||||
.unwrap_or_else(|| {
|
||||
let stdout = io::stdout();
|
||||
Box::new(NoColorTerminal::new(stdout)) as StdoutTerminal
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets a terminal that supports color if available.
|
||||
#[cfg(not(windows))]
|
||||
fn term_stdout(color: bool) -> StdoutTerminal {
|
||||
let stdout = io::stdout();
|
||||
if !color || TERMINFO.is_none() {
|
||||
Box::new(NoColorTerminal::new(stdout))
|
||||
} else {
|
||||
let info = TERMINFO.clone().unwrap();
|
||||
Box::new(TerminfoTerminal::new_with_terminfo(stdout, info))
|
||||
}
|
||||
}
|
||||
use terminal_win::WindowsBuffer;
|
||||
|
||||
/// Out controls the actual output of all search results for a particular file
|
||||
/// to the end user.
|
||||
@@ -43,16 +16,31 @@ fn term_stdout(color: bool) -> StdoutTerminal {
|
||||
/// individual search results where as Out works with search results for each
|
||||
/// file as a whole. For example, it knows when to print a file separator.)
|
||||
pub struct Out {
|
||||
term: StdoutTerminal,
|
||||
#[cfg(not(windows))]
|
||||
term: ColoredTerminal<term::TerminfoTerminal<io::BufWriter<io::Stdout>>>,
|
||||
#[cfg(windows)]
|
||||
term: ColoredTerminal<WinConsole<io::Stdout>>,
|
||||
printed: bool,
|
||||
file_separator: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Out {
|
||||
/// Create a new Out that writes to the wtr given.
|
||||
#[cfg(not(windows))]
|
||||
pub fn new(color: bool) -> Out {
|
||||
let wtr = io::BufWriter::new(io::stdout());
|
||||
Out {
|
||||
term: ColoredTerminal::new(wtr, color),
|
||||
printed: false,
|
||||
file_separator: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new Out that writes to the wtr given.
|
||||
#[cfg(windows)]
|
||||
pub fn new(color: bool) -> Out {
|
||||
Out {
|
||||
term: term_stdout(color),
|
||||
term: ColoredTerminal::new_stdout(color),
|
||||
printed: false,
|
||||
file_separator: None,
|
||||
}
|
||||
@@ -69,154 +57,194 @@ impl Out {
|
||||
|
||||
/// Write the search results of a single file to the underlying wtr and
|
||||
/// flush wtr.
|
||||
pub fn write(&mut self, buf: &OutBuffer) {
|
||||
#[cfg(not(windows))]
|
||||
pub fn write(
|
||||
&mut self,
|
||||
buf: &ColoredTerminal<term::TerminfoTerminal<Vec<u8>>>,
|
||||
) {
|
||||
self.write_sep();
|
||||
match *buf {
|
||||
ColoredTerminal::Colored(ref tt) => {
|
||||
let _ = self.term.write_all(tt.get_ref());
|
||||
}
|
||||
ColoredTerminal::NoColor(ref buf) => {
|
||||
let _ = self.term.write_all(buf);
|
||||
}
|
||||
}
|
||||
self.write_done();
|
||||
}
|
||||
/// Write the search results of a single file to the underlying wtr and
|
||||
/// flush wtr.
|
||||
#[cfg(windows)]
|
||||
pub fn write(
|
||||
&mut self,
|
||||
buf: &ColoredTerminal<WindowsBuffer>,
|
||||
) {
|
||||
self.write_sep();
|
||||
match *buf {
|
||||
ColoredTerminal::Colored(ref tt) => {
|
||||
tt.print_stdout(&mut self.term);
|
||||
}
|
||||
ColoredTerminal::NoColor(ref buf) => {
|
||||
let _ = self.term.write_all(buf);
|
||||
}
|
||||
}
|
||||
self.write_done();
|
||||
}
|
||||
|
||||
fn write_sep(&mut self) {
|
||||
if let Some(ref sep) = self.file_separator {
|
||||
if self.printed {
|
||||
let _ = self.term.write_all(sep);
|
||||
let _ = self.term.write_all(b"\n");
|
||||
}
|
||||
}
|
||||
match *buf {
|
||||
OutBuffer::Colored(ref tt) => {
|
||||
let _ = self.term.write_all(tt.get_ref());
|
||||
}
|
||||
OutBuffer::Windows(ref w) => {
|
||||
w.print_stdout(&mut self.term);
|
||||
}
|
||||
OutBuffer::NoColor(ref buf) => {
|
||||
let _ = self.term.write_all(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_done(&mut self) {
|
||||
let _ = self.term.flush();
|
||||
self.printed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// OutBuffer corresponds to the final output buffer for search results. All
|
||||
/// search results are written to a buffer and then a buffer is flushed to
|
||||
/// stdout only after the full search has completed.
|
||||
/// ColoredTerminal provides optional colored output through the term::Terminal
|
||||
/// trait. In particular, it will dynamically configure itself to use coloring
|
||||
/// if it's available in the environment.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum OutBuffer {
|
||||
Colored(TerminfoTerminal<Vec<u8>>),
|
||||
Windows(WindowsBuffer),
|
||||
NoColor(Vec<u8>),
|
||||
pub enum ColoredTerminal<T: Terminal + Send> {
|
||||
Colored(T),
|
||||
NoColor(T::Output),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WindowsBuffer {
|
||||
buf: Vec<u8>,
|
||||
pos: usize,
|
||||
colors: Vec<WindowsColor>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WindowsColor {
|
||||
pos: usize,
|
||||
opt: WindowsOption,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum WindowsOption {
|
||||
Foreground(Color),
|
||||
Background(Color),
|
||||
Reset,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref TERMINFO: Option<Arc<TermInfo>> = {
|
||||
match TermInfo::from_env() {
|
||||
Ok(info) => Some(Arc::new(info)),
|
||||
Err(err) => {
|
||||
debug!("error loading terminfo for coloring: {}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl OutBuffer {
|
||||
#[cfg(not(windows))]
|
||||
impl<W: io::Write + Send> ColoredTerminal<term::TerminfoTerminal<W>> {
|
||||
/// Create a new output buffer.
|
||||
///
|
||||
/// When color is true, the buffer will attempt to support coloring.
|
||||
pub fn new(color: bool) -> OutBuffer {
|
||||
// If we want color, build a TerminfoTerminal and see if the current
|
||||
// environment supports coloring. If not, bail with NoColor. To avoid
|
||||
// losing our writer (ownership), do this the long way.
|
||||
pub fn new(wtr: W, color: bool) -> Self {
|
||||
lazy_static! {
|
||||
// Only pay for parsing the terminfo once.
|
||||
static ref TERMINFO: Option<TermInfo> = {
|
||||
match TermInfo::from_env() {
|
||||
Ok(info) => Some(info),
|
||||
Err(err) => {
|
||||
debug!("error loading terminfo for coloring: {}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// If we want color, build a term::TerminfoTerminal and see if the
|
||||
// current environment supports coloring. If not, bail with NoColor. To
|
||||
// avoid losing our writer (ownership), do this the long way.
|
||||
if !color {
|
||||
return OutBuffer::NoColor(vec![]);
|
||||
return ColoredTerminal::NoColor(wtr);
|
||||
}
|
||||
if cfg!(windows) {
|
||||
return OutBuffer::Windows(WindowsBuffer {
|
||||
buf: vec![],
|
||||
pos: 0,
|
||||
colors: vec![]
|
||||
});
|
||||
}
|
||||
if TERMINFO.is_none() {
|
||||
return OutBuffer::NoColor(vec![]);
|
||||
}
|
||||
let info = TERMINFO.clone().unwrap();
|
||||
let tt = TerminfoTerminal::new_with_terminfo(vec![], info);
|
||||
let terminfo = match *TERMINFO {
|
||||
None => return ColoredTerminal::NoColor(wtr),
|
||||
Some(ref ti) => {
|
||||
// Ug, this should go away with the next release of `term`.
|
||||
TermInfo {
|
||||
names: ti.names.clone(),
|
||||
bools: ti.bools.clone(),
|
||||
numbers: ti.numbers.clone(),
|
||||
strings: ti.strings.clone(),
|
||||
}
|
||||
}
|
||||
};
|
||||
let tt = term::TerminfoTerminal::new_with_terminfo(wtr, terminfo);
|
||||
if !tt.supports_color() {
|
||||
debug!("environment doesn't support coloring");
|
||||
return OutBuffer::NoColor(tt.into_inner());
|
||||
return ColoredTerminal::NoColor(tt.into_inner());
|
||||
}
|
||||
ColoredTerminal::Colored(tt)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
impl ColoredTerminal<term::TerminfoTerminal<Vec<u8>>> {
|
||||
/// Clear the give buffer of all search results such that it is reusable
|
||||
/// in another search.
|
||||
pub fn clear(&mut self) {
|
||||
match *self {
|
||||
ColoredTerminal::Colored(ref mut tt) => {
|
||||
tt.get_mut().clear();
|
||||
}
|
||||
ColoredTerminal::NoColor(ref mut buf) => {
|
||||
buf.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl ColoredTerminal<WindowsBuffer> {
|
||||
/// Create a new output buffer.
|
||||
///
|
||||
/// When color is true, the buffer will attempt to support coloring.
|
||||
pub fn new_buffer(color: bool) -> Self {
|
||||
if !color {
|
||||
ColoredTerminal::NoColor(vec![])
|
||||
} else {
|
||||
ColoredTerminal::Colored(WindowsBuffer::new())
|
||||
}
|
||||
OutBuffer::Colored(tt)
|
||||
}
|
||||
|
||||
/// Clear the give buffer of all search results such that it is reusable
|
||||
/// in another search.
|
||||
pub fn clear(&mut self) {
|
||||
match *self {
|
||||
OutBuffer::Colored(ref mut tt) => {
|
||||
tt.get_mut().clear();
|
||||
}
|
||||
OutBuffer::Windows(ref mut win) => {
|
||||
win.buf.clear();
|
||||
win.colors.clear();
|
||||
win.pos = 0;
|
||||
}
|
||||
OutBuffer::NoColor(ref mut buf) => {
|
||||
buf.clear();
|
||||
}
|
||||
ColoredTerminal::Colored(ref mut win) => win.clear(),
|
||||
ColoredTerminal::NoColor(ref mut buf) => buf.clear(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn map_result<F, G>(
|
||||
#[cfg(windows)]
|
||||
impl ColoredTerminal<WinConsole<io::Stdout>> {
|
||||
/// Create a new output buffer.
|
||||
///
|
||||
/// When color is true, the buffer will attempt to support coloring.
|
||||
pub fn new_stdout(color: bool) -> Self {
|
||||
if !color {
|
||||
return ColoredTerminal::NoColor(io::stdout());
|
||||
}
|
||||
match WinConsole::new(io::stdout()) {
|
||||
Ok(win) => ColoredTerminal::Colored(win),
|
||||
Err(_) => ColoredTerminal::NoColor(io::stdout()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Terminal + Send> ColoredTerminal<T> {
|
||||
fn map_result<F>(
|
||||
&mut self,
|
||||
mut f: F,
|
||||
mut g: G,
|
||||
) -> term::Result<()>
|
||||
where F: FnMut(&mut TerminfoTerminal<Vec<u8>>) -> term::Result<()>,
|
||||
G: FnMut(&mut WindowsBuffer) -> term::Result<()> {
|
||||
where F: FnMut(&mut T) -> term::Result<()> {
|
||||
match *self {
|
||||
OutBuffer::Colored(ref mut w) => f(w),
|
||||
OutBuffer::Windows(ref mut w) => g(w),
|
||||
OutBuffer::NoColor(_) => Err(term::Error::NotSupported),
|
||||
ColoredTerminal::Colored(ref mut w) => f(w),
|
||||
ColoredTerminal::NoColor(_) => Err(term::Error::NotSupported),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_bool<F, G>(
|
||||
fn map_bool<F>(
|
||||
&self,
|
||||
mut f: F,
|
||||
mut g: G,
|
||||
) -> bool
|
||||
where F: FnMut(&TerminfoTerminal<Vec<u8>>) -> bool,
|
||||
G: FnMut(&WindowsBuffer) -> bool {
|
||||
where F: FnMut(&T) -> bool {
|
||||
match *self {
|
||||
OutBuffer::Colored(ref w) => f(w),
|
||||
OutBuffer::Windows(ref w) => g(w),
|
||||
OutBuffer::NoColor(_) => false,
|
||||
ColoredTerminal::Colored(ref w) => f(w),
|
||||
ColoredTerminal::NoColor(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for OutBuffer {
|
||||
impl<T: Terminal + Send> io::Write for ColoredTerminal<T> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match *self {
|
||||
OutBuffer::Colored(ref mut w) => w.write(buf),
|
||||
OutBuffer::Windows(ref mut w) => w.write(buf),
|
||||
OutBuffer::NoColor(ref mut w) => w.write(buf),
|
||||
ColoredTerminal::Colored(ref mut w) => w.write(buf),
|
||||
ColoredTerminal::NoColor(ref mut w) => w.write(buf),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,259 +253,67 @@ impl io::Write for OutBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
impl term::Terminal for OutBuffer {
|
||||
type Output = Vec<u8>;
|
||||
impl<T: Terminal + Send> term::Terminal for ColoredTerminal<T> {
|
||||
type Output = T::Output;
|
||||
|
||||
fn fg(&mut self, fg: term::color::Color) -> term::Result<()> {
|
||||
self.map_result(|w| w.fg(fg), |w| w.fg(fg))
|
||||
self.map_result(|w| w.fg(fg))
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: term::color::Color) -> term::Result<()> {
|
||||
self.map_result(|w| w.bg(bg), |w| w.bg(bg))
|
||||
self.map_result(|w| w.bg(bg))
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: term::Attr) -> term::Result<()> {
|
||||
self.map_result(|w| w.attr(attr), |w| w.attr(attr))
|
||||
self.map_result(|w| w.attr(attr))
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: term::Attr) -> bool {
|
||||
self.map_bool(|w| w.supports_attr(attr), |w| w.supports_attr(attr))
|
||||
self.map_bool(|w| w.supports_attr(attr))
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.reset(), |w| w.reset())
|
||||
self.map_result(|w| w.reset())
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
self.map_bool(|w| w.supports_reset(), |w| w.supports_reset())
|
||||
self.map_bool(|w| w.supports_reset())
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
self.map_bool(|w| w.supports_color(), |w| w.supports_color())
|
||||
self.map_bool(|w| w.supports_color())
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.cursor_up(), |w| w.cursor_up())
|
||||
self.map_result(|w| w.cursor_up())
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.delete_line(), |w| w.delete_line())
|
||||
self.map_result(|w| w.delete_line())
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
self.map_result(|w| w.carriage_return(), |w| w.carriage_return())
|
||||
self.map_result(|w| w.carriage_return())
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &Vec<u8> {
|
||||
fn get_ref(&self) -> &Self::Output {
|
||||
match *self {
|
||||
OutBuffer::Colored(ref w) => w.get_ref(),
|
||||
OutBuffer::Windows(ref w) => w.get_ref(),
|
||||
OutBuffer::NoColor(ref w) => w,
|
||||
ColoredTerminal::Colored(ref w) => w.get_ref(),
|
||||
ColoredTerminal::NoColor(ref w) => w,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut Vec<u8> {
|
||||
fn get_mut(&mut self) -> &mut Self::Output {
|
||||
match *self {
|
||||
OutBuffer::Colored(ref mut w) => w.get_mut(),
|
||||
OutBuffer::Windows(ref mut w) => w.get_mut(),
|
||||
OutBuffer::NoColor(ref mut w) => w,
|
||||
ColoredTerminal::Colored(ref mut w) => w.get_mut(),
|
||||
ColoredTerminal::NoColor(ref mut w) => w,
|
||||
}
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Vec<u8> {
|
||||
fn into_inner(self) -> Self::Output {
|
||||
match self {
|
||||
OutBuffer::Colored(w) => w.into_inner(),
|
||||
OutBuffer::Windows(w) => w.into_inner(),
|
||||
OutBuffer::NoColor(w) => w,
|
||||
ColoredTerminal::Colored(w) => w.into_inner(),
|
||||
ColoredTerminal::NoColor(w) => w,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowsBuffer {
|
||||
fn push(&mut self, opt: WindowsOption) {
|
||||
let pos = self.pos;
|
||||
self.colors.push(WindowsColor { pos: pos, opt: opt });
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowsBuffer {
|
||||
/// Print the contents to the given terminal.
|
||||
pub fn print_stdout(&self, tt: &mut StdoutTerminal) {
|
||||
if !tt.supports_color() {
|
||||
let _ = tt.write_all(&self.buf);
|
||||
let _ = tt.flush();
|
||||
return;
|
||||
}
|
||||
let mut last = 0;
|
||||
for col in &self.colors {
|
||||
let _ = tt.write_all(&self.buf[last..col.pos]);
|
||||
match col.opt {
|
||||
WindowsOption::Foreground(c) => {
|
||||
let _ = tt.fg(c);
|
||||
}
|
||||
WindowsOption::Background(c) => {
|
||||
let _ = tt.bg(c);
|
||||
}
|
||||
WindowsOption::Reset => {
|
||||
let _ = tt.reset();
|
||||
}
|
||||
}
|
||||
last = col.pos;
|
||||
}
|
||||
let _ = tt.write_all(&self.buf[last..]);
|
||||
let _ = tt.flush();
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for WindowsBuffer {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let n = try!(self.buf.write(buf));
|
||||
self.pos += n;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl term::Terminal for WindowsBuffer {
|
||||
type Output = Vec<u8>;
|
||||
|
||||
fn fg(&mut self, fg: term::color::Color) -> term::Result<()> {
|
||||
self.push(WindowsOption::Foreground(fg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: term::color::Color) -> term::Result<()> {
|
||||
self.push(WindowsOption::Background(bg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: term::Attr) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: term::Attr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
self.push(WindowsOption::Reset);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &Vec<u8> {
|
||||
&self.buf
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut Vec<u8> {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Vec<u8> {
|
||||
self.buf
|
||||
}
|
||||
}
|
||||
|
||||
/// NoColorTerminal implements Terminal, but supports no coloring.
|
||||
///
|
||||
/// Its useful when an API requires a Terminal, but coloring isn't needed.
|
||||
pub struct NoColorTerminal<W> {
|
||||
wtr: W,
|
||||
}
|
||||
|
||||
impl<W: Send + io::Write> NoColorTerminal<W> {
|
||||
/// Wrap the given writer in a Terminal interface.
|
||||
pub fn new(wtr: W) -> NoColorTerminal<W> {
|
||||
NoColorTerminal {
|
||||
wtr: wtr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Send + io::Write> io::Write for NoColorTerminal<W> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.wtr.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.wtr.flush()
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Send + io::Write> term::Terminal for NoColorTerminal<W> {
|
||||
type Output = W;
|
||||
|
||||
fn fg(&mut self, fg: term::color::Color) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: term::color::Color) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: term::Attr) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: term::Attr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &W {
|
||||
&self.wtr
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut W {
|
||||
&mut self.wtr
|
||||
}
|
||||
|
||||
fn into_inner(self) -> W {
|
||||
self.wtr
|
||||
}
|
||||
}
|
||||
|
100
src/pathutil.rs
Normal file
100
src/pathutil.rs
Normal file
@@ -0,0 +1,100 @@
|
||||
/*!
|
||||
The pathutil module provides platform specific operations on paths that are
|
||||
typically faster than the same operations as provided in std::path. In
|
||||
particular, we really want to avoid the costly operation of parsing the path
|
||||
into its constituent components. We give up on Windows, but on Unix, we deal
|
||||
with the raw bytes directly.
|
||||
|
||||
On large repositories (like chromium), this can have a ~25% performance
|
||||
improvement on just listing the files to search (!).
|
||||
*/
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
|
||||
/// Strip `prefix` from the `path` and return the remainder.
|
||||
///
|
||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||
#[cfg(unix)]
|
||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
prefix: &'a P,
|
||||
path: &'a Path,
|
||||
) -> Option<&'a Path> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
let prefix = prefix.as_ref().as_os_str().as_bytes();
|
||||
let path = path.as_os_str().as_bytes();
|
||||
if prefix.len() > path.len() || prefix != &path[0..prefix.len()] {
|
||||
None
|
||||
} else {
|
||||
Some(&Path::new(OsStr::from_bytes(&path[prefix.len()..])))
|
||||
}
|
||||
}
|
||||
|
||||
/// Strip `prefix` from the `path` and return the remainder.
|
||||
///
|
||||
/// If `path` doesn't have a prefix `prefix`, then return `None`.
|
||||
#[cfg(not(unix))]
|
||||
pub fn strip_prefix<'a, P: AsRef<Path> + ?Sized>(
|
||||
prefix: &'a P,
|
||||
path: &'a Path,
|
||||
) -> Option<&'a Path> {
|
||||
path.strip_prefix(prefix).ok()
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(unix)]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use memchr::memrchr;
|
||||
|
||||
let path = path.as_ref().as_os_str().as_bytes();
|
||||
if path.is_empty() {
|
||||
return None;
|
||||
} else if path.len() == 1 && path[0] == b'.' {
|
||||
return None;
|
||||
} else if path.last() == Some(&b'.') {
|
||||
return None;
|
||||
} else if path.len() >= 2 && &path[path.len() - 2..] == &b".."[..] {
|
||||
return None;
|
||||
}
|
||||
let last_slash = memrchr(b'/', path).map(|i| i + 1).unwrap_or(0);
|
||||
Some(OsStr::from_bytes(&path[last_slash..]))
|
||||
}
|
||||
|
||||
/// The final component of the path, if it is a normal file.
|
||||
///
|
||||
/// If the path terminates in ., .., or consists solely of a root of prefix,
|
||||
/// file_name will return None.
|
||||
#[cfg(not(unix))]
|
||||
pub fn file_name<'a, P: AsRef<Path> + ?Sized>(
|
||||
path: &'a P,
|
||||
) -> Option<&'a OsStr> {
|
||||
path.as_ref().file_name()
|
||||
}
|
||||
|
||||
/// Returns true if and only if this file path is considered to be hidden.
|
||||
#[cfg(unix)]
|
||||
pub fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
if let Some(name) = file_name(path.as_ref()) {
|
||||
name.as_bytes().get(0) == Some(&b'.')
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if and only if this file path is considered to be hidden.
|
||||
#[cfg(not(unix))]
|
||||
pub fn is_hidden<P: AsRef<Path>>(path: P) -> bool {
|
||||
if let Some(name) = file_name(path.as_ref()) {
|
||||
name.to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
@@ -36,7 +36,7 @@ pub struct Printer<W> {
|
||||
with_filename: bool,
|
||||
}
|
||||
|
||||
impl<W: Send + Terminal> Printer<W> {
|
||||
impl<W: Terminal + Send> Printer<W> {
|
||||
/// Create a new printer that writes to wtr.
|
||||
pub fn new(wtr: W) -> Printer<W> {
|
||||
Printer {
|
||||
|
@@ -151,10 +151,10 @@ impl<'a, W: Send + Terminal> BufferSearcher<'a, W> {
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
||||
use grep::{Grep, GrepBuilder};
|
||||
use term::Terminal;
|
||||
use grep::GrepBuilder;
|
||||
use term::{Terminal, TerminfoTerminal};
|
||||
|
||||
use out::OutBuffer;
|
||||
use out::ColoredTerminal;
|
||||
use printer::Printer;
|
||||
|
||||
use super::BufferSearcher;
|
||||
@@ -168,38 +168,19 @@ but Doctor Watson has to have it taken out for him and dusted,
|
||||
and exhibited clearly, with a label attached.\
|
||||
";
|
||||
|
||||
const CODE: &'static str = "\
|
||||
extern crate snap;
|
||||
|
||||
use std::io;
|
||||
|
||||
fn main() {
|
||||
let stdin = io::stdin();
|
||||
let stdout = io::stdout();
|
||||
|
||||
// Wrap the stdin reader in a Snappy reader.
|
||||
let mut rdr = snap::Reader::new(stdin.lock());
|
||||
let mut wtr = stdout.lock();
|
||||
io::copy(&mut rdr, &mut wtr).expect(\"I/O operation failed\");
|
||||
}
|
||||
";
|
||||
|
||||
fn matcher(pat: &str) -> Grep {
|
||||
GrepBuilder::new(pat).build().unwrap()
|
||||
}
|
||||
|
||||
fn test_path() -> &'static Path {
|
||||
&Path::new("/baz.rs")
|
||||
}
|
||||
|
||||
type TestSearcher<'a> = BufferSearcher<'a, OutBuffer>;
|
||||
type TestSearcher<'a> =
|
||||
BufferSearcher<'a, ColoredTerminal<TerminfoTerminal<Vec<u8>>>>;
|
||||
|
||||
fn search<F: FnMut(TestSearcher) -> TestSearcher>(
|
||||
pat: &str,
|
||||
haystack: &str,
|
||||
mut map: F,
|
||||
) -> (u64, String) {
|
||||
let outbuf = OutBuffer::NoColor(vec![]);
|
||||
let outbuf = ColoredTerminal::NoColor(vec![]);
|
||||
let mut pp = Printer::new(outbuf).with_filename(true);
|
||||
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||
let count = {
|
||||
|
@@ -100,7 +100,7 @@ impl Default for Options {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: io::Read, W: Send + Terminal> Searcher<'a, R, W> {
|
||||
impl<'a, R: io::Read, W: Terminal + Send> Searcher<'a, R, W> {
|
||||
/// Create a new searcher.
|
||||
///
|
||||
/// `inp` is a reusable input buffer that is used as scratch space by this
|
||||
@@ -763,10 +763,10 @@ mod tests {
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
use grep::{Grep, GrepBuilder};
|
||||
use term::Terminal;
|
||||
use grep::GrepBuilder;
|
||||
use term::{Terminal, TerminfoTerminal};
|
||||
|
||||
use out::OutBuffer;
|
||||
use out::ColoredTerminal;
|
||||
use printer::Printer;
|
||||
|
||||
use super::{InputBuffer, Searcher, start_of_previous_lines};
|
||||
@@ -800,15 +800,15 @@ fn main() {
|
||||
io::Cursor::new(s.to_string().into_bytes())
|
||||
}
|
||||
|
||||
fn matcher(pat: &str) -> Grep {
|
||||
GrepBuilder::new(pat).build().unwrap()
|
||||
}
|
||||
|
||||
fn test_path() -> &'static Path {
|
||||
&Path::new("/baz.rs")
|
||||
}
|
||||
|
||||
type TestSearcher<'a> = Searcher<'a, io::Cursor<Vec<u8>>, OutBuffer>;
|
||||
type TestSearcher<'a> = Searcher<
|
||||
'a,
|
||||
io::Cursor<Vec<u8>>,
|
||||
ColoredTerminal<TerminfoTerminal<Vec<u8>>>,
|
||||
>;
|
||||
|
||||
fn search_smallcap<F: FnMut(TestSearcher) -> TestSearcher>(
|
||||
pat: &str,
|
||||
@@ -816,7 +816,7 @@ fn main() {
|
||||
mut map: F,
|
||||
) -> (u64, String) {
|
||||
let mut inp = InputBuffer::with_capacity(1);
|
||||
let outbuf = OutBuffer::NoColor(vec![]);
|
||||
let outbuf = ColoredTerminal::NoColor(vec![]);
|
||||
let mut pp = Printer::new(outbuf).with_filename(true);
|
||||
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||
let count = {
|
||||
@@ -833,7 +833,7 @@ fn main() {
|
||||
mut map: F,
|
||||
) -> (u64, String) {
|
||||
let mut inp = InputBuffer::with_capacity(4096);
|
||||
let outbuf = OutBuffer::NoColor(vec![]);
|
||||
let outbuf = ColoredTerminal::NoColor(vec![]);
|
||||
let mut pp = Printer::new(outbuf).with_filename(true);
|
||||
let grep = GrepBuilder::new(pat).build().unwrap();
|
||||
let count = {
|
||||
|
202
src/terminal.rs
202
src/terminal.rs
@@ -1,202 +0,0 @@
|
||||
/*!
|
||||
This module contains an implementation of the `term::Terminal` trait.
|
||||
|
||||
The actual implementation is copied almost verbatim from the `term` crate, so
|
||||
this code is under the same license (MIT/Apache).
|
||||
|
||||
The specific reason why this is copied here is to wrap an Arc<TermInfo> instead
|
||||
of a TermInfo. This makes multithreaded sharing much more performant.
|
||||
|
||||
N.B. This is temporary until this issue is fixed:
|
||||
https://github.com/Stebalien/term/issues/64
|
||||
*/
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::sync::Arc;
|
||||
|
||||
use term::{Attr, Error, Result, Terminal, color};
|
||||
use term::terminfo::TermInfo;
|
||||
use term::terminfo::parm::{Param, Variables, expand};
|
||||
|
||||
/// A Terminal that knows how many colors it supports, with a reference to its
|
||||
/// parsed Terminfo database record.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TerminfoTerminal<T> {
|
||||
num_colors: u16,
|
||||
out: T,
|
||||
ti: Arc<TermInfo>,
|
||||
}
|
||||
|
||||
impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
|
||||
type Output = T;
|
||||
fn fg(&mut self, color: color::Color) -> Result<()> {
|
||||
let color = self.dim_if_necessary(color);
|
||||
if self.num_colors > color {
|
||||
return apply_cap(&self.ti, "setaf", &[Param::Number(color as i32)], &mut self.out);
|
||||
}
|
||||
Err(Error::ColorOutOfRange)
|
||||
}
|
||||
|
||||
fn bg(&mut self, color: color::Color) -> Result<()> {
|
||||
let color = self.dim_if_necessary(color);
|
||||
if self.num_colors > color {
|
||||
return apply_cap(&self.ti, "setab", &[Param::Number(color as i32)], &mut self.out);
|
||||
}
|
||||
Err(Error::ColorOutOfRange)
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: Attr) -> Result<()> {
|
||||
match attr {
|
||||
Attr::ForegroundColor(c) => self.fg(c),
|
||||
Attr::BackgroundColor(c) => self.bg(c),
|
||||
_ => apply_cap(&self.ti, cap_for_attr(attr), &[], &mut self.out),
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: Attr) -> bool {
|
||||
match attr {
|
||||
Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
|
||||
_ => {
|
||||
let cap = cap_for_attr(attr);
|
||||
self.ti.strings.get(cap).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> Result<()> {
|
||||
reset(&self.ti, &mut self.out)
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
["sgr0", "sgr", "op"].iter().any(|&cap| self.ti.strings.get(cap).is_some())
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
self.num_colors > 0 && self.supports_reset()
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> Result<()> {
|
||||
apply_cap(&self.ti, "cuu1", &[], &mut self.out)
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> Result<()> {
|
||||
apply_cap(&self.ti, "dl", &[], &mut self.out)
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> Result<()> {
|
||||
apply_cap(&self.ti, "cr", &[], &mut self.out)
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &T {
|
||||
&self.out
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.out
|
||||
}
|
||||
|
||||
fn into_inner(self) -> T
|
||||
where Self: Sized
|
||||
{
|
||||
self.out
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Write + Send> TerminfoTerminal<T> {
|
||||
/// Create a new TerminfoTerminal with the given TermInfo and Write.
|
||||
pub fn new_with_terminfo(out: T, terminfo: Arc<TermInfo>) -> TerminfoTerminal<T> {
|
||||
let nc = if terminfo.strings.contains_key("setaf") &&
|
||||
terminfo.strings.contains_key("setab") {
|
||||
terminfo.numbers.get("colors").map_or(0, |&n| n)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
TerminfoTerminal {
|
||||
out: out,
|
||||
ti: terminfo,
|
||||
num_colors: nc,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new TerminfoTerminal for the current environment with the given Write.
|
||||
///
|
||||
/// Returns `None` when the terminfo cannot be found or parsed.
|
||||
pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
|
||||
TermInfo::from_env().map(move |ti| {
|
||||
TerminfoTerminal::new_with_terminfo(out, Arc::new(ti))
|
||||
}).ok()
|
||||
}
|
||||
|
||||
fn dim_if_necessary(&self, color: color::Color) -> color::Color {
|
||||
if color >= self.num_colors && color >= 8 && color < 16 {
|
||||
color - 8
|
||||
} else {
|
||||
color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Write> Write for TerminfoTerminal<T> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.out.write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.out.flush()
|
||||
}
|
||||
}
|
||||
|
||||
fn cap_for_attr(attr: Attr) -> &'static str {
|
||||
match attr {
|
||||
Attr::Bold => "bold",
|
||||
Attr::Dim => "dim",
|
||||
Attr::Italic(true) => "sitm",
|
||||
Attr::Italic(false) => "ritm",
|
||||
Attr::Underline(true) => "smul",
|
||||
Attr::Underline(false) => "rmul",
|
||||
Attr::Blink => "blink",
|
||||
Attr::Standout(true) => "smso",
|
||||
Attr::Standout(false) => "rmso",
|
||||
Attr::Reverse => "rev",
|
||||
Attr::Secure => "invis",
|
||||
Attr::ForegroundColor(_) => "setaf",
|
||||
Attr::BackgroundColor(_) => "setab",
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_cap(ti: &TermInfo, cmd: &str, params: &[Param], out: &mut io::Write) -> Result<()> {
|
||||
match ti.strings.get(cmd) {
|
||||
Some(cmd) => {
|
||||
match expand(cmd, params, &mut Variables::new()) {
|
||||
Ok(s) => {
|
||||
try!(out.write_all(&s));
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
None => Err(Error::NotSupported),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(ti: &TermInfo, out: &mut io::Write) -> Result<()> {
|
||||
// are there any terminals that have color/attrs and not sgr0?
|
||||
// Try falling back to sgr, then op
|
||||
let cmd = match [("sgr0", &[] as &[Param]), ("sgr", &[Param::Number(0)]), ("op", &[])]
|
||||
.iter()
|
||||
.filter_map(|&(cap, params)| {
|
||||
ti.strings.get(cap).map(|c| (c, params))
|
||||
})
|
||||
.next() {
|
||||
Some((op, params)) => {
|
||||
match expand(op, params, &mut Variables::new()) {
|
||||
Ok(cmd) => cmd,
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
None => return Err(Error::NotSupported),
|
||||
};
|
||||
try!(out.write_all(&cmd));
|
||||
Ok(())
|
||||
}
|
||||
|
176
src/terminal_win.rs
Normal file
176
src/terminal_win.rs
Normal file
@@ -0,0 +1,176 @@
|
||||
/*!
|
||||
This module contains a Windows-only *in-memory* implementation of the
|
||||
`term::Terminal` trait.
|
||||
|
||||
This particular implementation is a bit idiosyncratic, and the "in-memory"
|
||||
specification is to blame. In particular, on Windows, coloring requires
|
||||
communicating with the console synchronously as data is written to stdout.
|
||||
This is anathema to how ripgrep fundamentally works: by writing search results
|
||||
to intermediate thread local buffers in order to maximize parallelism.
|
||||
|
||||
Eliminating parallelism on Windows isn't an option, because that would negate
|
||||
a tremendous performance benefit just for coloring.
|
||||
|
||||
We've worked around this by providing an implementation of `term::Terminal`
|
||||
that records precisely where a color or a reset should be invoked, according
|
||||
to a byte offset in the in memory buffer. When the buffer is actually printed,
|
||||
we copy the bytes from the buffer to stdout incrementally while invoking the
|
||||
corresponding console APIs for coloring at the right location.
|
||||
|
||||
(Another approach would be to do ANSI coloring unconditionally, then parse that
|
||||
and translate it to console commands. The advantage of that approach is that
|
||||
it doesn't require any additional memory for storing offsets. In practice
|
||||
though, coloring is only used in the terminal, which tends to correspond to
|
||||
searches that produce very few results with respect to the corpus searched.
|
||||
Therefore, this is an acceptable trade off. Namely, we do not pay for it when
|
||||
coloring is disabled.
|
||||
*/
|
||||
use std::io;
|
||||
|
||||
use term::{self, Terminal};
|
||||
use term::color::Color;
|
||||
|
||||
/// An in-memory buffer that provides Windows console coloring.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WindowsBuffer {
|
||||
buf: Vec<u8>,
|
||||
pos: usize,
|
||||
colors: Vec<WindowsColor>,
|
||||
}
|
||||
|
||||
/// A color associated with a particular location in a buffer.
|
||||
#[derive(Clone, Debug)]
|
||||
struct WindowsColor {
|
||||
pos: usize,
|
||||
opt: WindowsOption,
|
||||
}
|
||||
|
||||
/// A color or reset directive that can be translated into an instruction to
|
||||
/// the Windows console.
|
||||
#[derive(Clone, Debug)]
|
||||
enum WindowsOption {
|
||||
Foreground(Color),
|
||||
Background(Color),
|
||||
Reset,
|
||||
}
|
||||
|
||||
impl WindowsBuffer {
|
||||
/// Create a new empty buffer for Windows console coloring.
|
||||
pub fn new() -> WindowsBuffer {
|
||||
WindowsBuffer {
|
||||
buf: vec![],
|
||||
pos: 0,
|
||||
colors: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn push(&mut self, opt: WindowsOption) {
|
||||
let pos = self.pos;
|
||||
self.colors.push(WindowsColor { pos: pos, opt: opt });
|
||||
}
|
||||
|
||||
/// Print the contents to the given terminal.
|
||||
pub fn print_stdout<T: Terminal + Send>(&self, tt: &mut T) {
|
||||
if !tt.supports_color() {
|
||||
let _ = tt.write_all(&self.buf);
|
||||
let _ = tt.flush();
|
||||
return;
|
||||
}
|
||||
let mut last = 0;
|
||||
for col in &self.colors {
|
||||
let _ = tt.write_all(&self.buf[last..col.pos]);
|
||||
match col.opt {
|
||||
WindowsOption::Foreground(c) => {
|
||||
let _ = tt.fg(c);
|
||||
}
|
||||
WindowsOption::Background(c) => {
|
||||
let _ = tt.bg(c);
|
||||
}
|
||||
WindowsOption::Reset => {
|
||||
let _ = tt.reset();
|
||||
}
|
||||
}
|
||||
last = col.pos;
|
||||
}
|
||||
let _ = tt.write_all(&self.buf[last..]);
|
||||
let _ = tt.flush();
|
||||
}
|
||||
|
||||
/// Clear the buffer.
|
||||
pub fn clear(&mut self) {
|
||||
self.buf.clear();
|
||||
self.colors.clear();
|
||||
self.pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for WindowsBuffer {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let n = try!(self.buf.write(buf));
|
||||
self.pos += n;
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Terminal for WindowsBuffer {
|
||||
type Output = Vec<u8>;
|
||||
|
||||
fn fg(&mut self, fg: Color) -> term::Result<()> {
|
||||
self.push(WindowsOption::Foreground(fg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bg(&mut self, bg: Color) -> term::Result<()> {
|
||||
self.push(WindowsOption::Background(bg));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn attr(&mut self, _attr: term::Attr) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn supports_attr(&self, _attr: term::Attr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> term::Result<()> {
|
||||
self.push(WindowsOption::Reset);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn supports_reset(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_color(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn cursor_up(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn delete_line(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn carriage_return(&mut self) -> term::Result<()> {
|
||||
Err(term::Error::NotSupported)
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &Vec<u8> {
|
||||
&self.buf
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut Vec<u8> {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Vec<u8> {
|
||||
self.buf
|
||||
}
|
||||
}
|
175
src/types.rs
175
src/types.rs
@@ -8,7 +8,10 @@ use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
|
||||
use gitignore::{self, Gitignore, GitignoreBuilder, Match, Pattern};
|
||||
use regex;
|
||||
|
||||
use gitignore::{Match, Pattern};
|
||||
use glob::{self, MatchOptions};
|
||||
|
||||
const TYPE_EXTENSIONS: &'static [(&'static str, &'static [&'static str])] = &[
|
||||
("asm", &["*.asm", "*.s", "*.S"]),
|
||||
@@ -55,6 +58,7 @@ const TYPE_EXTENSIONS: &'static [(&'static str, &'static [&'static str])] = &[
|
||||
("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm"]),
|
||||
("php", &["*.php", "*.php3", "*.php4", "*.php5", "*.phtml"]),
|
||||
("py", &["*.py"]),
|
||||
("readme", &["README*", "*README"]),
|
||||
("rr", &["*.R"]),
|
||||
("rst", &["*.rst"]),
|
||||
("ruby", &["*.rb"]),
|
||||
@@ -81,7 +85,9 @@ pub enum Error {
|
||||
/// A user specified file type definition could not be parsed.
|
||||
InvalidDefinition,
|
||||
/// There was an error building the matcher (probably a bad glob).
|
||||
Gitignore(gitignore::Error),
|
||||
Glob(glob::Error),
|
||||
/// There was an error compiling a glob as a regex.
|
||||
Regex(regex::Error),
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
@@ -89,7 +95,8 @@ impl StdError for Error {
|
||||
match *self {
|
||||
Error::UnrecognizedFileType(_) => "unrecognized file type",
|
||||
Error::InvalidDefinition => "invalid definition",
|
||||
Error::Gitignore(ref err) => err.description(),
|
||||
Error::Glob(ref err) => err.description(),
|
||||
Error::Regex(ref err) => err.description(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,14 +111,21 @@ impl fmt::Display for Error {
|
||||
write!(f, "invalid definition (format is type:glob, e.g., \
|
||||
html:*.html)")
|
||||
}
|
||||
Error::Gitignore(ref err) => err.fmt(f),
|
||||
Error::Glob(ref err) => err.fmt(f),
|
||||
Error::Regex(ref err) => err.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<gitignore::Error> for Error {
|
||||
fn from(err: gitignore::Error) -> Error {
|
||||
Error::Gitignore(err)
|
||||
impl From<glob::Error> for Error {
|
||||
fn from(err: glob::Error) -> Error {
|
||||
Error::Glob(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<regex::Error> for Error {
|
||||
fn from(err: regex::Error) -> Error {
|
||||
Error::Regex(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +151,8 @@ impl FileTypeDef {
|
||||
/// Types is a file type matcher.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Types {
|
||||
gi: Option<Gitignore>,
|
||||
selected: Option<glob::SetYesNo>,
|
||||
negated: Option<glob::SetYesNo>,
|
||||
has_selected: bool,
|
||||
unmatched_pat: Pattern,
|
||||
}
|
||||
@@ -149,14 +164,19 @@ impl Types {
|
||||
///
|
||||
/// If has_selected is true, then at least one file type was selected.
|
||||
/// Therefore, any non-matches should be ignored.
|
||||
fn new(gi: Option<Gitignore>, has_selected: bool) -> Types {
|
||||
fn new(
|
||||
selected: Option<glob::SetYesNo>,
|
||||
negated: Option<glob::SetYesNo>,
|
||||
has_selected: bool,
|
||||
) -> Types {
|
||||
Types {
|
||||
gi: gi,
|
||||
selected: selected,
|
||||
negated: negated,
|
||||
has_selected: has_selected,
|
||||
unmatched_pat: Pattern {
|
||||
from: Path::new("<filetype>").to_path_buf(),
|
||||
original: "<none>".to_string(),
|
||||
pat: "<none>".to_string(),
|
||||
original: "<N/A>".to_string(),
|
||||
pat: "<N/A>".to_string(),
|
||||
whitelist: false,
|
||||
only_dir: false,
|
||||
},
|
||||
@@ -165,7 +185,7 @@ impl Types {
|
||||
|
||||
/// Creates a new file type matcher that never matches.
|
||||
pub fn empty() -> Types {
|
||||
Types::new(None, false)
|
||||
Types::new(None, None, false)
|
||||
}
|
||||
|
||||
/// Returns a match for the given path against this file type matcher.
|
||||
@@ -175,22 +195,35 @@ impl Types {
|
||||
/// If at least one file type is selected and path doesn't match, then
|
||||
/// the path is also considered ignored.
|
||||
pub fn matched<P: AsRef<Path>>(&self, path: P, is_dir: bool) -> Match {
|
||||
// If we don't have any matcher, then we can't do anything.
|
||||
if self.negated.is_none() && self.selected.is_none() {
|
||||
return Match::None;
|
||||
}
|
||||
// File types don't apply to directories.
|
||||
if is_dir {
|
||||
return Match::None;
|
||||
}
|
||||
let path = path.as_ref();
|
||||
self.gi.as_ref()
|
||||
.map(|gi| {
|
||||
let path = &*path.to_string_lossy();
|
||||
let mat = gi.matched_utf8(path, is_dir).invert();
|
||||
if self.has_selected && mat.is_none() {
|
||||
Match::Ignored(&self.unmatched_pat)
|
||||
} else {
|
||||
mat
|
||||
}
|
||||
})
|
||||
.unwrap_or(Match::None)
|
||||
let name = match path.file_name() {
|
||||
Some(name) => name.to_string_lossy(),
|
||||
None if self.has_selected => {
|
||||
return Match::Ignored(&self.unmatched_pat);
|
||||
}
|
||||
None => {
|
||||
return Match::None;
|
||||
}
|
||||
};
|
||||
if self.negated.as_ref().map(|s| s.is_match(&*name)).unwrap_or(false) {
|
||||
return Match::Ignored(&self.unmatched_pat);
|
||||
}
|
||||
if self.selected.as_ref().map(|s|s.is_match(&*name)).unwrap_or(false) {
|
||||
return Match::Whitelist(&self.unmatched_pat);
|
||||
}
|
||||
if self.has_selected {
|
||||
Match::Ignored(&self.unmatched_pat)
|
||||
} else {
|
||||
Match::None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,8 +231,8 @@ impl Types {
|
||||
/// a set of file type selections.
|
||||
pub struct TypesBuilder {
|
||||
types: HashMap<String, Vec<String>>,
|
||||
select: Vec<String>,
|
||||
select_not: Vec<String>,
|
||||
selected: Vec<String>,
|
||||
negated: Vec<String>,
|
||||
}
|
||||
|
||||
impl TypesBuilder {
|
||||
@@ -207,41 +240,57 @@ impl TypesBuilder {
|
||||
pub fn new() -> TypesBuilder {
|
||||
TypesBuilder {
|
||||
types: HashMap::new(),
|
||||
select: vec![],
|
||||
select_not: vec![],
|
||||
selected: vec![],
|
||||
negated: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the current set of file type definitions *and* selections into
|
||||
/// a file type matcher.
|
||||
pub fn build(&self) -> Result<Types, Error> {
|
||||
if self.select.is_empty() && self.select_not.is_empty() {
|
||||
return Ok(Types::new(None, false));
|
||||
}
|
||||
let mut bgi = GitignoreBuilder::new("/");
|
||||
for name in &self.select {
|
||||
let globs = match self.types.get(name) {
|
||||
Some(globs) => globs,
|
||||
None => {
|
||||
return Err(Error::UnrecognizedFileType(name.to_string()));
|
||||
let opts = MatchOptions {
|
||||
require_literal_separator: true, ..MatchOptions::default()
|
||||
};
|
||||
let selected_globs =
|
||||
if self.selected.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut bset = glob::SetBuilder::new();
|
||||
for name in &self.selected {
|
||||
let globs = match self.types.get(name) {
|
||||
Some(globs) => globs,
|
||||
None => {
|
||||
let msg = name.to_string();
|
||||
return Err(Error::UnrecognizedFileType(msg));
|
||||
}
|
||||
};
|
||||
for glob in globs {
|
||||
try!(bset.add_with(glob, &opts));
|
||||
}
|
||||
}
|
||||
Some(try!(bset.build_yesno()))
|
||||
};
|
||||
for glob in globs {
|
||||
try!(bgi.add("<filetype>", glob));
|
||||
}
|
||||
}
|
||||
for name in &self.select_not {
|
||||
let globs = match self.types.get(name) {
|
||||
Some(globs) => globs,
|
||||
None => {
|
||||
return Err(Error::UnrecognizedFileType(name.to_string()));
|
||||
let negated_globs =
|
||||
if self.negated.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut bset = glob::SetBuilder::new();
|
||||
for name in &self.negated {
|
||||
let globs = match self.types.get(name) {
|
||||
Some(globs) => globs,
|
||||
None => {
|
||||
let msg = name.to_string();
|
||||
return Err(Error::UnrecognizedFileType(msg));
|
||||
}
|
||||
};
|
||||
for glob in globs {
|
||||
try!(bset.add_with(glob, &opts));
|
||||
}
|
||||
}
|
||||
Some(try!(bset.build_yesno()))
|
||||
};
|
||||
for glob in globs {
|
||||
try!(bgi.add("<filetype>", &format!("!{}", glob)));
|
||||
}
|
||||
}
|
||||
Ok(Types::new(Some(try!(bgi.build())), !self.select.is_empty()))
|
||||
Ok(Types::new(
|
||||
selected_globs, negated_globs, !self.selected.is_empty()))
|
||||
}
|
||||
|
||||
/// Return the set of current file type definitions.
|
||||
@@ -260,14 +309,30 @@ impl TypesBuilder {
|
||||
}
|
||||
|
||||
/// Select the file type given by `name`.
|
||||
///
|
||||
/// If `name` is `all`, then all file types are selected.
|
||||
pub fn select(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
self.select.push(name.to_string());
|
||||
if name == "all" {
|
||||
for name in self.types.keys() {
|
||||
self.selected.push(name.to_string());
|
||||
}
|
||||
} else {
|
||||
self.selected.push(name.to_string());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Ignore the file type given by `name`.
|
||||
pub fn select_not(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
self.select_not.push(name.to_string());
|
||||
///
|
||||
/// If `name` is `all`, then all file types are negated.
|
||||
pub fn negate(&mut self, name: &str) -> &mut TypesBuilder {
|
||||
if name == "all" {
|
||||
for name in self.types.keys() {
|
||||
self.negated.push(name.to_string());
|
||||
}
|
||||
} else {
|
||||
self.negated.push(name.to_string());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
@@ -333,7 +398,7 @@ mod tests {
|
||||
btypes.select(sel);
|
||||
}
|
||||
for selnot in $selnot {
|
||||
btypes.select_not(selnot);
|
||||
btypes.negate(selnot);
|
||||
}
|
||||
let types = btypes.build().unwrap();
|
||||
let mat = types.matched($path, false);
|
||||
|
@@ -26,6 +26,7 @@ impl Iter {
|
||||
}
|
||||
|
||||
/// Returns true if this entry should be skipped.
|
||||
#[inline(always)]
|
||||
fn skip_entry(&self, ent: &DirEntry) -> bool {
|
||||
if ent.depth() == 0 {
|
||||
// Never skip the root directory.
|
||||
@@ -41,6 +42,7 @@ impl Iter {
|
||||
impl Iterator for Iter {
|
||||
type Item = DirEntry;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<DirEntry> {
|
||||
while let Some(ev) = self.it.next() {
|
||||
match ev {
|
||||
@@ -108,6 +110,7 @@ impl From<WalkDir> for WalkEventIter {
|
||||
impl Iterator for WalkEventIter {
|
||||
type Item = walkdir::Result<WalkEvent>;
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<walkdir::Result<WalkEvent>> {
|
||||
let dent = self.next.take().or_else(|| self.it.next());
|
||||
let depth = match dent {
|
||||
@@ -135,8 +138,3 @@ impl Iterator for WalkEventIter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_hidden(ent: &DirEntry) -> bool {
|
||||
ent.depth() > 0 &&
|
||||
ent.file_name().to_str().map(|s| s.starts_with(".")).unwrap_or(false)
|
||||
}
|
||||
|
@@ -166,7 +166,7 @@ For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
|
||||
sherlock!(literal, "()", "file", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create("file", "blib\n()\nblab\n");
|
||||
cmd.arg("-Q");
|
||||
cmd.arg("-F");
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "()\n");
|
||||
});
|
||||
@@ -219,6 +219,13 @@ sherlock!(file_types, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
assert_eq!(lines, "file.rs:Sherlock\n");
|
||||
});
|
||||
|
||||
sherlock!(file_types_all, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create("file.py", "Sherlock");
|
||||
cmd.arg("-t").arg("all");
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "file.py:Sherlock\n");
|
||||
});
|
||||
|
||||
sherlock!(file_types_negate, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.remove("sherlock");
|
||||
wd.create("file.py", "Sherlock");
|
||||
@@ -228,6 +235,18 @@ sherlock!(file_types_negate, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
assert_eq!(lines, "file.py:Sherlock\n");
|
||||
});
|
||||
|
||||
sherlock!(file_types_negate_all, "Sherlock", ".",
|
||||
|wd: WorkDir, mut cmd: Command| {
|
||||
wd.create("file.py", "Sherlock");
|
||||
cmd.arg("-T").arg("all");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "\
|
||||
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
");
|
||||
});
|
||||
|
||||
sherlock!(file_type_clear, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create("file.py", "Sherlock");
|
||||
wd.create("file.rs", "Sherlock");
|
||||
@@ -506,6 +525,50 @@ baz/sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
}
|
||||
});
|
||||
|
||||
sherlock!(unrestricted1, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create(".gitignore", "sherlock\n");
|
||||
cmd.arg("-u");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
let expected = "\
|
||||
sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
";
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
sherlock!(unrestricted2, "Sherlock", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.remove("sherlock");
|
||||
wd.create(".sherlock", hay::SHERLOCK);
|
||||
cmd.arg("-uu");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
let expected = "\
|
||||
.sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock
|
||||
.sherlock:be, to a very large extent, the result of luck. Sherlock Holmes
|
||||
";
|
||||
assert_eq!(lines, expected);
|
||||
});
|
||||
|
||||
#[cfg(not(windows))]
|
||||
sherlock!(unrestricted3, "foo", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create("file", "foo\x00bar\nfoo\x00baz\n");
|
||||
cmd.arg("-uuu");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "file:foo\nfile:foo\n");
|
||||
});
|
||||
|
||||
// On Windows, this test uses memory maps, so the NUL bytes don't get replaced.
|
||||
#[cfg(windows)]
|
||||
sherlock!(unrestricted3, "foo", ".", |wd: WorkDir, mut cmd: Command| {
|
||||
wd.create("file", "foo\x00bar\nfoo\x00baz\n");
|
||||
cmd.arg("-uuu");
|
||||
|
||||
let lines: String = wd.stdout(&mut cmd);
|
||||
assert_eq!(lines, "file:foo\x00bar\nfile:foo\x00baz\n");
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn binary_nosearch() {
|
||||
let wd = WorkDir::new("binary_nosearch");
|
||||
|
Reference in New Issue
Block a user