Tại sao 'grep -i' lại chậm như vậy? Làm thế nào để làm điều đó nhanh hơn cho ASCII?


2

Xem xét:

$ time lzop -d < tvtropes-index.lzo | egrep -B 5 '[Dd][eE][sS][cC][eE][nN][dD] ?[Ff][rR][oO][mM]'
real    0m0.438s

$ time lzop -d < tvtropes-index.lzo | egrep -B 5 'descend ?from' -i
real    0m11.294s

Cả hai trường hợp tìm kiếm vô cảm. Tại sao -iphiên bản quá chậm? Làm cách nào để thực hiện grep -inhanh mà không cần nhập những thứ như [iI] [nN] [tT] [hH] [iI] [sS] [wW] [aA] [Yy]?

Ví dụ,

perl -ne 'print if /descend ?from/i'

hoạt động nhanh, nhưng '-B 5' không tầm thường để thực hiện như trong grep (cũng như các tùy chọn khác).


1
Không nhạy cảm trường hợp là khó, đặc biệt là nếu bạn đang làm điều đó trên đầu vào unicode.
phogg

Làm cách nào để làm cho trường hợp không nhạy cảm nhanh, ví dụ như "thay thế mọi x bằng [xX] trong mẫu"?
Vi.

Câu trả lời:


6

Trường hợp gấp là khó khăn

Chỉ cần ánh xạ [az] sang [AZ] cho hầu hết các tài liệu văn bản chỉ ASCII đơn giản. Tuy nhiên, nó bắt đầu bị hỏng khi chúng tôi khám phá các ngôn ngữ khác sử dụng các ký tự bổ sung. Nó cũng không tính đến thực tế là ánh xạ trường hợp trong một số ngôn ngữ không phải lúc nào cũng là thuật toán hoặc tĩnh.

Ví dụ: nếu bạn gập [az] -> [AZ], một chuỗi như "Dürst" hoặc "résumé" có thể sẽ trông hơi kỳ lạ: "DüRST" hoặc "RéSUMé".

Bạn có thể tăng tốc nó bằng cách thuyết phục grep rằng thế giới là ASCII một lần nữa, bằng cách sử dụng một grep cổ đại hoặc bằng cách chơi với các địa phương (LC_ALL = C?).

Cuộc trò chuyện này có đề cập đến "sự chậm chạp lớn trên các địa điểm UTF8" nhưng không có ích.


Có chế độ không nhạy cảm trường hợp nhanh chỉ có ASCII cho grep không? LANG=C grep -ithất bại (chậm).
Vi.

@Vi: lzop -d < thingy | tr '[A-Z]' '[a-z]' | grep ... có thể?
RedGrittyBrick

1
Xin lỗi, "LANG = C grep -i" hoạt động (được kiểm tra lại một cách chính xác).
Vi.

2

Giả thuyết

Những kết quả phản trực giác được giải thích bởi điều này. Regex của bạn không giống như grep -igrep -itổng quát hơn, có tính đến việc xử lý chuỗi nhiều byte phức tạp, ít nhất là khi được biên dịch bằng ký hiệu tiền xử lý MBS_SUPPORT.

Hãy xem ở đây:

http://cvs.savannah.gnu.org/viewvc/grep/grep/src/search.c?revision=1.42&view=markup

Hãy tìm match_icaseMBS_SUPPORT.


0

Nếu trường hợp thực tế của việc tìm kiếm không quan trọng, bạn có thể sử dụng trđể gấp [A-Z]lại [a-z]trước grep.


Tôi sẽ chỉ làm điều đó để có một regex đơn giản hơn để viết. Mặc dù regex không phân biệt chữ hoa chữ thường có thể tạo ra một DFA lớn hơn, nhưng đây có lẽ không phải là vấn đề lớn. Nó phụ thuộc vào có bao nhiêu trận đấu. Nếu tệp có nhiều kết quả dương tính giả hoặc khớp hoàn toàn sử dụng nhiều kết hợp trường hợp có thể, thì biểu đồ trạng thái sẽ lưu trữ xấu trong CPU. Điều đó có lẽ không phát sinh. Có lẽ sẽ chỉ có một vài trường hợp như DESCEND, Hậu duệ đi xuống theo cùng một con đường "trodden" thông qua DFA regex.
Kaz
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.