2017-12-04 9 views
1

많은 폴더, 파일 (.css, .py, .yml 등) 및 코드 줄이있는 파이썬 프로젝트가 있습니다.파이썬에서 파일 및 번호 라인 수를 최적화하십시오.

글로벌 통계 :

전체 프로젝트 : 32,329 선
프로젝트의 주요 파일 (평이 프로젝트를 위해, 나는 나에게 등 전체 프로젝트에 대한 정보를 제공합니다 "통계"라는 도구를 만든 , .yml) :: 8420 선 공급 업체의 일부 :: 1070 선
코어 (src 디렉토리) : 394 선없이
프로젝트
코어의 주요 파일 : 5 % 크라켄 프레임 워크 (공급 업체에 프로젝트 비교/*. 평) :: 7350 라인
홈페이지 파일 파이썬 코드 : 93 %
공급 업체 파이썬 코드 : 87 %
전체 프로젝트 크기 : 37M

은, 모든 번호를 얻으려면 나는 주로 두 가지 기능을 사용

def count_folder_lines(self, path): 
    files = glob.glob(path, recursive=True) 
    number = 0 
    for file in files: 
     num_lines = sum(1 for line in open(file)) 
     number += num_lines 
    return number 

def count_number_of_files(self, path): 
    files = glob.glob(path, recursive=True) 
    return len(files) 

첫번째 폴더와의 행의 수를 계산하는 데 사용되는 두 번째 파일은 특정 파일 수를 계산하는 데 사용됩니다 (예 : src/*. py). 그러나 프로젝트의 통계를 얻으려면 4.9 초에서 5.3 초 사이가 필요합니다.

더 빨리 만들 수있는 방법이 있습니까? 병렬 프로그래밍이나 Cython을 사용하면 뭔가가 바뀔까요?

좋은 하루 되십시오. 감사합니다.

+0

파일 크기를 보면 훨씬 더 빠를 것입니다. – Ora

+0

제 경우에는 실제로 행의 수가 필요합니다. – vmele

+0

문제는 항상 가장 긴 파일로 제한된다는 것입니다. 나는 나에게 그것을 시험해 보았다. 그리고 20,000 개의 줄의 파일을 위해, 그것은 2,3 초 걸릴 수있다. 코드 행은 자주 변경되지 않는 번호입니다. 그러므로 필자의 제안 : 컴파일과 병행하여 결과를 계산하는 스크립트를 실행하거나 (읽기만하는 경우) 스크립트를 실행하거나 x 분 또는 시간마다 계산하도록 백그라운드 작업을 실행하십시오. 두 경우 모두 결과를 파일로 출력 한 다음 필요할 때마다 간단히 읽습니다. – Ora

답변

0

마지막으로 나를위한 가장 효율적인 해결책을 찾았습니다. 각 파일의 행 수를 병렬로 계산하기 위해 다중 처리 모듈을 사용하고 있습니다. 이 솔루션을

def count_folder_lines(self, path): 
    """ 
     Use a buffer to count the number of line of each file among path. 
     :param path: string pattern of a file type 
     :return: number of lines in matching files 
    """ 
    files = glob.glob(path, recursive=True) 
    number = 0 
    for file in files: 
     f = open(file, 'rb') 
     bufgen = takewhile(lambda x: x, 
          (f.raw.read(1024 * 1024) for _ in repeat(None))) 
     number += sum(buf.count(b'\n') for buf in bufgen if buf) 
    return number 

def count_number_of_files(self, path): 
    """ 
     Count number of files for a string pattern 
     :param path: files string pattern 
     :return: number of files matching the pattern 
    """ 
    files = glob.glob(path, recursive=True) 
    return len(files) 

def multiproc(self): 
    """ 
     Multiprocessing to launch several processes to count number of 
     lines of each string pattern in self.files 
     :return: List of number of files per string pattern 
        (list of int). 
    """ 
    pool = mp.Pool() 
    asyncResult = pool.map_async(self.count_folder_lines, self.files) 
    return asyncResult.get() 

, 그것은 전 ~ 대 5 초를 세는 ~ 1.2s 걸립니다.

좋은 하루 되세요!