텍스트 파일의 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

따라서 세 번째 접근 방식은 824,789개의 명령입니다. 첫 번째 방법보다 훨씬 낫습니다.


네 번째 개선된 방법

$ 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

두 번째 방법보다 조금 더 나쁩니다. 어쨌든 세 번째 방법과 마찬가지로 작동합니다.


파일에 대해 동일한 테스트를 반복하여 어떤 방법이 가장 효과적인지 확인할 수 있습니다.


두 번째 측정 방법:

$ 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. 파일에서 특정 줄을 얻는 방법은 무엇입니까?

관련 정보