2011-12-07 3 views
1

큰 코드베이스와 다른 도구를 통해 여러 번 읽어야 할 수도 있습니다. 그런 다음 텍스트가 변경되지 않는 동안 디스크에서 여러 번 읽는 것이 실제 낭비라고 생각하여 다음을 작성했습니다.캐싱 디스크 작업

class Module(object): 
    def __init__(self, module_path): 
     self.module_path = module_path 
     self._text = None 
     self._ast = None 

    @property 
    def text(self): 
     if not self._text: 
      self._text = open(self.module_path).read() 
     return self._text 

    @property 
    def ast(self): 
     s = self.text # which is actually discarded 
     if not self._ast: 
      self._ast = parse(self.text) 

     return self._ast 


class ContentDirectory(object): 
    def __init__(self): 
     self.content = {} 

    def __getitem__(self, module_path): 
     if module_path not in self.content: 
      self.content[module_path] = Module(module_path) 

     return self.content[module_path] 

하지만이 새로운 트릭을 사용할 수있는 반면 나머지 코드는 변경하지 않으려 고하므로 문제가 발생합니다. 내가 볼

있는 유일한 방법은 예를 들어, 사용 할 수있는 모든 곳에서 "열기"내장 기능을 패치하는 것입니다.

from myotherlib import __builtins__ as other_builtins 
other_builtins.open = my_dummy_open # which uses this cache 

은 그러나 정말 현명한 생각이 아닌 것 같아. 나는 단지 포기해야만하고, 그 성능이 너무 나쁠 경우에만 시도해야합니까? 이 라이브러리가 제공하는 기능은 시나리오에있는 사용이다, 그러나 그럼에도 불구하고 linecache library의 존재를 언급하는 것을 생각하면

+3

"난 그냥 포기하고 성능이 어쩌면 정말 너무 나쁜 경우에만 시도해야 하는가?" - 거의 확실합니다. OS 레벨은 파일 캐싱을 처리합니다. 더 잘 할 수 있다면 (예 : OS보다 액세스 패턴을 더 잘 이해할 수 있다면) 캐싱 할 가치가 있지만 실제로 먼저해야 할 필요가있는 경우 항상 가치가 있습니다. –

+0

'parse()'에 실제로 걸리는 시간은 얼마나됩니까? 얼마나 자주 다시 구문 분석을 할 수 있습니까? 프로세스/컴퓨터가'_ast'가 실제로 사용하지만 사용되지 않는 메모리에 더 유용한 것을 할 수 있습니까? – sarnold

+0

OS는 기적을 일으킬 수 없으며, 작은 테스트에서 캐시 된 버전과 캐시되지 않은 버전 간의 시간차가 큽니다. 특히 많은 파일을 분석 할 경우 특히 그렇습니다. –

답변

1

는 잘 모르겠어요. 링크 된 문서에서 :

linecache 모듈은 내부적으로 최적화를 시도 캐시, 많은 행이 하나의 파일에서 읽기 일반적인 경우를 사용하는 동안 하나, 모든 파일의 모든 라인을 얻을 수 있습니다. 시스템 open() 전화를 교체

이 우아하고 투명한 방식으로 솔루션을 구현의 문제에 근처에도 오지 않는다 물론

...

2

잠재적으로 나쁜 일이다. open()을 사용하는 모든 것이 예상대로 사용되어야합니다.

왜 코드를 변경하지 않으시겠습니까?

예, 성능을 측정하고 가치가 있는지 확인하십시오. 예를 들어, 위의 코드를 입력하고 얼마나 빠른 것들이 있는지보십시오. 1 % 빠르면 아무것도 할 이유가 없습니다. 속도가 훨씬 빠르다면 open()을 사용하고있는 것을보고 가능한 경우 해당 코드를 변경하십시오.

참고로, LRU cache (부분은 functools, Python 3.2에 있음) 또한 작업에 도움이됩니다.