2014-04-21 3 views
0

filecmp.cmp을 사용하여 두 디렉토리의 파일을 비교하는 Python 스크립트를 작성했습니다. 그것은 작동하지만 지금 막 거대한 파일의 집합을 위해 그것을 달리기를 시도했다. 그것은 매우 느렸다.'shallow'매개 변수가 True 인 경우에도 거대한 파일에 대해 filecmp.cmp가 느린 이유는 무엇입니까?

shallow 매개 변수가 true (기본값) 인 경우 filecmp.cmpos.stat 결과 만 비교해야한다고 설명합니다.

jpg 파일의 또 다른 큰 컬렉션에 대해 스크립트가 훨씬 빠르게 실행되었습니다. 파일 크기가 파일 수보다 큰 이유가 궁금해서 os.stat 만 확인하면됩니다.

답변

2

shallow 매개 변수에 대한 설명서가 오해의 소지가 있다고 생각합니다 *. shallow = True을 전달한다고해서 반드시 filecmp.cmp 함수가 파일의 내용을 비교할 수있는 것은 아닙니다. 파일의 크기가 같지만 크기가 다르지만 mtime이 다를 경우 해당 내용은 계속 확인됩니다.

파이썬 설치에서 cmp의 구현을 보거나 Python source repository에서 (이 순간의 현재 시점) 소스를 볼 수 있습니다.

def cmp(f1, f2, shallow=True): 
    # long docstring removed 

    s1 = _sig(os.stat(f1)) 
    s2 = _sig(os.stat(f2)) 
    if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG: 
     return False 
    if shallow and s1 == s2: 
     return True 
    if s1[1] != s2[1]: 
     return False 

    # rest of function, which calls a helper to do the actual file contents comparisons 

_sig 도우미 함수는 파일의 stat 데이터 구조로부터 추출 된 값 터플을 반환 여기

cmp의 중요한 비트이다. 튜플 값은 파일 유형, 파일 크기 및 mtime (일반적으로 파일 내용이 마지막으로 수정 된 시간)입니다.

코드 발췌에 포함 된 테스트는 해당 메타 데이터를 기반으로 두 파일이 동일한 지 빠르게 판단하려고합니다. 두 파일 중 하나가 "일반"파일이 아닌 경우 (디렉토리 또는 특수 시스템 파일이기 때문에) 파일은 불균등 한 것으로 간주됩니다. 또한, 그들이 같은 크기가 아니라면, 그들은 아마도 동등 할 수 없습니다.

shallow 매개 변수는 빠른 양성 테스트를 허용합니다. shallow이 true이고 파일의 크기가 동일하고 mtime 인 경우 filecmp.cmp은 파일이 같다고 가정합니다.

당신의 프로그램에서 현재 일어나고있는 의심스러운 점은 현재 디렉토리에 정확히 같은 크기의 파일이 있다는 것입니다 (아마도 매우 유사한 내용 때문이거나 파일 크기가 데이터 형식으로 고정되어 있기 때문일 수 있습니다). 이전 데이터 세트에는 동일한 크기의 파일이 많지 않으므로 코드에서 신속하게 제거 할 수있었습니다.

* filecmp.cmp의 docstring이 버그를 나타내는 것으로 오인 된 것이라고 생각합니다. (제대로 동작을 설명하지 않았거나 실제 구현이 올바르지 않아서 문서와 일치하도록 수정해야하기 때문입니다). 그리고 나는 혼자가 아닌 것처럼 보입니다. 이 문제에 대해서는 Here is a bug report이지만 몇 년 후에는 업데이트되지 않았습니다. 이 질문에 대한 링크로 버그를 핑 (ping)하고 누군가가 수정하려고합니다!

+0

당신을위한 정보. fyi, jpeg의 수집은 빠른 실행 스크립트는 2G, mts 컬렉션은 약 24G입니다. 그냥 ls -la comparsion에 대한 mts의 두 dir, 눈 검사에 의해 파일의 대부분이 날짜와 크기가 바이트와 같기 때문에, 스크립트는 diff 명으로 파일을 건너 뛸 것입니다. 스크립트에서 내용 검사를 실행할 수있는 mtime diff와 다른 조건을 검사에서? 인용 한 코드 발췌에서 도우미에게 전화 할 조건이 표시되지 않았습니다. – timeislove

+0

은 filecmp.cmp 순수 pythonic이거나 C 함수 호출을 필요로합니까?파이썬에서 모든 C 속도 라이브러리 내가 바이트 - 바이트 검사로 스크립트를 실행할 경우 성능 향상을 위해 호출 할 수 있습니다? – timeislove

+0

@timeislove :'filecmp' 모듈은 순수한 파이썬입니다.하지만 다른 모듈 (예 :'os.stat')에서 C 함수를 호출합니다. 파이썬 설치시'Lib/filecmp.py'를로드하여 전체 소스를 읽거나 파이썬 소스 저장소에서 현재 버전을 볼 수 있습니다 (http://hg.python.org/cpython/file /8c8315bac6a8/Lib/filecmp.py). 'cmp'에서 여분의 파일 스캔을 피할 수있는 유일한 방법은 (내 답변에서 발췌 한 것 이상으로) 캐시입니다.하지만 이것은 정확히 동일한 파일을 두 번 이상 서로 비교하는 것입니다. – Blckknght