テキストファイルのn行目を取得する最速の方法は何ですか

テキストファイルのn行目を取得する最速の方法は何ですか

m本の行を含むファイルが与えられたらn番目の行を取得する方法。 m は時々 n より小さい場合があります。私は試した:

method1: sed -ne '10p' file.txt
method2: sed -ne '10p' <file.txt
method3: sed -ne '10{p;q;}' file.txt
method4: awk 'NR==10' file.txt

LeetCodeからhttps://leetcode.com/problems/tenth-line/。方法1は他の方法より優れています。理由はわかりません。私は方法3がより速いと思います。

より速い方法がありますか?

修正する:

@skwllspの提案に従っていくつかのコマンドを実行しました。結果は次のとおりです。

instructions commands
428,160,537 perf stat sed -ne '10p' file.txt
427,426,310 perf stat sed -ne '10p' <file.txt
1,033,730   perf stat sed -ne '10{p;q;}' file.txt
1,111,502   perf stat awk 'NR == 10 { print ; exit ;} ' file.txt 

@Archemarの答えに従ってmethod4が変更されました。

そして

777,525 perf -stat tail -n +10 file.txt |head -n 1

これは方法1よりも費用がかなり安い。

答え1

テストを測定して、各メソッドが実行するコマンドの数を確認しましょう。独自のファイルを作成し、 seq 2000000 > 2000000.txtどのような方法が最速であるかを探しています。


$ perf stat sed -ne '10p' 2000000.txt 
10

 Performance counter stats for 'sed -ne 10p 2000000.txt':

        203.877247 task-clock                #    0.991 CPUs utilized          
                 5 context-switches          #    0.025 K/sec                  
                 3 cpu-migrations            #    0.015 K/sec                  
               214 page-faults               #    0.001 M/sec                  
       405,075,423 cycles                    #    1.987 GHz                     [50.20%]
   <not supported> stalled-cycles-frontend 
   <not supported> stalled-cycles-backend  
       838,221,677 instructions              #    2.07  insns per cycle         [75.20%]
       203,113,013 branches                  #  996.251 M/sec                   [74.99%]
           766,918 branch-misses             #    0.38% of all branches         [75.16%]

       0.205683270 seconds time elapsed

したがって、最初の方法は838,221,677のコマンドです。


$ perf stat sed -ne '10{p;q;}' 2000000.txt 
10

 Performance counter stats for 'sed -ne 10{p;q;} 2000000.txt':

          1.211558 task-clock                #    0.145 CPUs utilized          
                 2 context-switches          #    0.002 M/sec                  
                 0 cpu-migrations            #    0.000 K/sec                  
               213 page-faults               #    0.176 M/sec                  
         1,633,950 cycles                    #    1.349 GHz                     [23.73%]
   <not supported> stalled-cycles-frontend 
   <not supported> stalled-cycles-backend  
           824,789 instructions              #    0.50  insns per cycle        
           164,935 branches                  #  136.135 M/sec                  
            11,751 branch-misses             #    7.12% of all branches         [83.24%]

       0.008374725 seconds time elapsed

したがって、3番目のアプローチは824,789のコマンドです。最初の方法よりはるかに優れています。


4番目の改善された方法

$ perf stat awk 'NR == 10 { print ; exit ;} ' 2000000.txt 
10

 Performance counter stats for 'awk NR == 10 { print ; exit ;}  2000000.txt':

          1.357354 task-clock                #    0.162 CPUs utilized          
                 2 context-switches          #    0.001 M/sec                  
                 0 cpu-migrations            #    0.000 K/sec                  
               282 page-faults               #    0.208 M/sec                  
         1,777,749 cycles                    #    1.310 GHz                     [11.54%]
   <not supported> stalled-cycles-frontend 
   <not supported> stalled-cycles-backend  
           919,636 instructions              #    0.52  insns per cycle        
           185,695 branches                  #  136.807 M/sec                  
            11,218 branch-misses             #    6.04% of all branches         [91.64%]

       0.008375258 seconds time elapsed

2番目の方法より少し悪いです。とにかく、3番目の方法と同様に動作します。


ファイルに対して同じテストを繰り返して、どの方法が最も効果的であるかを確認できます。


2番目の測定方法:

$ perf stat sed -ne '10p' <2000000.txt 
10

 Performance counter stats for 'sed -ne 10p':

        203.278584 task-clock                #    0.998 CPUs utilized          
                 1 context-switches          #    0.005 K/sec                  
                 3 cpu-migrations            #    0.015 K/sec                  
               213 page-faults               #    0.001 M/sec                  
       403,941,976 cycles                    #    1.987 GHz                     [49.84%]
   <not supported> stalled-cycles-frontend 
   <not supported> stalled-cycles-backend  
       835,372,994 instructions              #    2.07  insns per cycle         [74.92%]
       203,327,145 branches                  # 1000.239 M/sec                   [74.90%]
           773,067 branch-misses             #    0.38% of all branches         [75.35%]

       0.203714402 seconds time elapsed

最初の方法と同じくらい悪いです。

答え2

awkのために

 awk 'NR == 10 { print ; exit ;} ' file.txt

私はPerlがより速いと思い、同じ問題がありましたここ約1年前。

また、見ることができます

  1. 大きなファイルのX行をY行に分類
  2. ファイルから特定の行を取得する方法は?

関連情報