Tôi chỉ muốn chỉ ra rằng gnu uniq
dường như rất chậm, ngay cả trong một danh sách được sắp xếp.
Tôi vừa thử nhận danh sách các tiền tố thư mục từ danh sách tên tệp được sắp xếp:
$ pv all_files | cut -d '/' -f 1,2,3,4 | uniq > all_prefixes
36.7GiB 0:07:41 [81.4MiB/s]
$ pv all_files | cut -d '/' -f 1,2,3,4 | sort -u > all_prefixes2
36.7GiB 0:03:14 [ 193MiB/s]
$ pv all_files | cut -d '/' -f 1,2,3,4 | awk '!x[$0]++' > all_prefixes3
36.7GiB 0:02:18 [ 270MiB/s]
sort -u có vẻ nhanh gấp đôi so với uniq, và điều này là với việc đọc sắp xếp từ stdin và viết đến stdout, vì vậy tôi không thấy nó thực hiện bất kỳ sự song song nào. Tôi không biết tại sao uniq nên chậm hơn rất nhiều sau đó sắp xếp, vì nó không phải sắp xếp danh sách ...
Outpuf của lệnh này là rất nhỏ (có rất nhiều bản sao), chỉ 264kb và sắp xếp chấm dứt ngay lập tức sau khi pv được thực hiện.
Tốc độ tương tự vẫn duy trì nếu bạn xoay quanh thứ tự các lệnh, luồng của tôi bị giới hạn bởi thời gian cpu ở đây, không phải truy cập đĩa và bộ nhớ cache (tôi chỉ có 8GB RAM và trao đổi của tôi không được sử dụng)
Tôi đang chạy cái này trên máy fedora 31 với loại gnu coreutils và uniq và gnu awk; ngôn ngữ được đặt thành en_US.UTF-8
CẬP NHẬT , vì điều này gây tò mò cho tôi khá nhiều, tôi đã thực hiện thêm một số thử nghiệm, hãy để phần cắt ra khỏi đường đi và đảm bảo tệp được sắp xếp độc đáo
cat all_files | cut -d '/' -f 1,2,3,4 | sort -T . > test
Điều này mất 8.4 phút. kiểm tra bây giờ là 7,9GB lớn
Hãy chạy các công cụ này trên tệp thay vì trong một đường ống, điều này sẽ cho phép các công cụ này thực hiện một số tối ưu hóa hơn, như sắp xếp sẽ đa luồng. và cũng từ một ssd nhanh hơn.
Bạn có thể không nhận thấy rằng sắp xếp cũng chiếm rất nhiều bộ nhớ, vì nó thực hiện các thủ thuật thông minh với các tệp tạm thời trong / tmp có thể là tmpfs và sẽ nằm trong ram của bạn (Hãy thử sắp xếp một tệp lớn hơn sau đó / tmp, bạn sẽ chạy vào không gian các vấn đề, đó là lý do tại sao tôi cần cờ -T. trong lệnh trên)
$ time sort -u test > /dev/null
339.24user 3.54system 1:28.87elapsed 385%CPU (0avgtext+0avgdata 2365856maxresident)k
9555544inputs+0outputs (0major+591298minor)pagefaults 0swaps
$ time awk '!x[$0]++' test > /dev/null
51.15user 1.55system 0:52.94elapsed 99%CPU (0avgtext+0avgdata 10976maxresident)k
0inputs+0outputs (0major+1923minor)pagefaults 0swaps
$ time uniq test > /dev/null
421.89user 2.76system 7:06.63elapsed 99%CPU (0avgtext+0avgdata 1980maxresident)k
52712inputs+0outputs (0major+79minor)pagefaults 0swaps
Vì vậy, có vẻ như giải pháp awk của bạn là nhanh nhất trong số 3 và thực sự sử dụng ít bộ nhớ nhất
update2
và bây giờ với ngôn ngữ đơn giản hơn
$ export LC_ALL=c
$ time sort -u test > /dev/null 1.2m ? Tue Apr 21 17:09:22 2020
119.18user 3.64system 0:38.24elapsed 321%CPU (0avgtext+0avgdata 2013472maxresident)k
$ time awk '!x[$0]++' test > /dev/null 1161ms ? Tue Apr 21 17:07:31 2020
67.23user 2.50system 1:10.16elapsed 99%CPU (0avgtext+0avgdata 10480maxresident)k
7187520inputs+0outputs (0major+1912minor)pagefaults 0swaps
$ time uniq test > /dev/null
22.05user 2.02system 0:24.24elapsed 99%CPU (0avgtext+0avgdata 1488maxresident)k
2959648inputs+0outputs (1major+72minor)pagefaults 0swaps
Lần này uniq chiến thắng cuộc đua ... vì Stéphane Chazelas gợi ý trong các bình luận, đặt ngôn ngữ của bạn thành C giúp sắp xếp và uniq nhanh hơn cả nhóm!
time
?