Unix grep có hoạt động nhanh hơn với các cụm từ tìm kiếm dài hay ngắn không?


8

Là nhanh hơn để tìm kiếm các cụm từ tìm kiếm dài hay ngắn? Hay nó ảnh hưởng đến tốc độ? Nói cách khác, bạn có nên làm cho thuật ngữ tìm kiếm càng chính xác càng tốt?

Có hơn 100 000 tệp và mỗi tệp chứa từ 20 đến hơn 5000 hàng dữ liệu. Thông thường grep được sử dụng để tìm chỉ một trường hợp của cụm từ tìm kiếm.

Giả sử thuật ngữ tìm kiếm là SEARCHTERMvà nó sẽ liên tiếp như thế này:

NAD+DP+1234567890:92++UNIQUE+NAME+SEARCHTERM++12345+FI'

Là nhanh hơn để tìm kiếm "TÌM KIẾM" hoặc "TÌM KIẾM"? Hãy nói rằng trong trường hợp này, chúng tôi không quan tâm nếu chúng tôi cũng tìm thấy kết quả khớp trong các dòng không liên quan khác.

Đây là cách tôi hiện đang làm điều đó:

grep NAD+DP 123* | grep SEARCHTERM

Nhưng tôi thấy nó khá chậm, vẫn còn. Thường mất khoảng 3-5 phút để tìm dữ liệu, ngay cả khi tôi biết tên tệp thô, giới hạn phạm vi trong khoảng 10 000 tệp.

Vì vậy, một thuật ngữ tìm kiếm dài hơn hoặc ngắn hơn sẽ giúp đỡ? Theo như tôi biết, grep tìm kiếm "khối" từ có độ dài nhất định?

Câu trả lời:


8

Một số tài liệu tham khảo:

GNU grep sử dụng thuật toán Boyer-Moore nổi tiếng, lần đầu tiên tìm chữ cái cuối cùng của chuỗi mục tiêu và sử dụng bảng tra cứu để cho biết nó có thể bỏ qua bao xa trong đầu vào bất cứ khi nào nó tìm thấy một ký tự không khớp.

từ Tại sao GNU grep lại nhanh .

Thuật toán tiền xử lý chuỗi đang được tìm kiếm (mẫu), nhưng không phải là chuỗi đang được tìm kiếm (văn bản). [...] Nói chung, thuật toán chạy nhanh hơn khi chiều dài mẫu tăng.

từ thuật toán tìm kiếm chuỗi BoyerTHER Moore .

Kết luận: Sử dụng chuỗi dài hơn .

Bây giờ, một chút điểm chuẩn cho vui:

# Initialisation
cd $(mktemp -d) && dd if=/dev/urandom of=random bs=1M count=1000
# Version
grep --v` # grep (GNU grep) 2.9
# Benchmark
(for s in 'short' 'this is not so short and we could even consider this as pretty long'; do for t in {1..10}; do time grep "$s" random; done; done ) 2> result

Kết quả: 0,952s là trung bình cho chuỗi ngắn, 0,244 giây là trung bình cho chuỗi dài.

NB : Độ dài không phải là tiêu chí duy nhất được tính đến.


0

Bạn có thể thử bản thân bằng TÌM KIẾM hoặc TÌM KIẾM. Cũng thử thay đổi thứ tự của hai lệnh grep. Dù sao, tùy chọn hữu ích duy nhất có thể sẽ sử dụng nhiều lõi CPU cho một tìm kiếm. Xem parallellệnh.


0

Tôi không nghĩ việc chỉ định thuật ngữ tìm kiếm cụ thể hơn sẽ làm cho nó nhanh hơn đáng kể.

Với rất nhiều tệp để tìm kiếm, bạn cần lập chỉ mục dữ liệu của mình để tìm kiếm nhanh hơn.

Tôi có thể đề xuất một vài cách:

  • Tạo cơ sở dữ liệu (PostgreSQL hoặc MySQL), nhập dữ liệu của bạn vào cơ sở dữ liệu - một tệp trong một hàng, thêm chỉ mục FTS (tìm kiếm toàn văn). Tạo một số tiện ích để truy vấn cơ sở dữ liệu.

  • Nhập dữ liệu vào cơ sở dữ liệu theo cách chi tiết hơn, có thể là một dòng thành một hàng (hoặc có thể nhiều hơn một bảng), tạo các chỉ mục sao cho dữ liệu của bạn có thể tìm kiếm được bằng cách sử dụng chỉ mục (es). Tạo một số tiện ích để truy vấn cơ sở dữ liệu.

  • Thêm tệp của bạn vào gitkho lưu trữ, nén nó bằng cách sử dụng git gc, sử dụng git grepđể tìm kiếm. Theo kinh nghiệm của tôi, git grepcó thể nhanh hơn tiêu chuẩn greptheo hệ số 10 x 100 lần.


0

Theo logic, một thuật ngữ ngắn hơn sẽ cần ít thời gian CPU hơn, như grepsẽ làm

if (filechar[i] == pattern[i]) ...

ít lần hơn Trong thực tế, tôi đoán rằng một cái grepsẽ bị ràng buộc I / O và không bị ràng buộc bởi CPU, vì vậy nó không thành vấn đề.


1
Đáng ngạc nhiên, điều này là sai vì grep đang sử dụng một thuật toán thực sự thông minh, xin vui lòng tham khảo câu trả lời của tôi.
SylvainD

chuỗi tìm kiếm càng dài, càng nhiều ký tự có thể bỏ qua khi tìm thấy sự không phù hợp, do đó tìm kiếm sẽ nhanh hơn
phuclv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.