Кеширование дисковых операций - PullRequest
1 голос
/ 07 декабря 2011

Мне может потребоваться выполнить многократное чтение по большой базе кода и с использованием различных инструментов. Затем я подумал, что это реальная трата, чтобы читать на диске так много раз, пока текст не изменится, поэтому я написал следующее.

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]

Но теперь возникает проблема, потому что я хотел бы избежать изменения остальной части кода, в то же время имея возможность использовать этот новый трюк.

Единственный способ, которым я вижу, - это исправлять встроенную функцию open везде, где ее можно использовать, например.

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

Но на самом деле это не похоже на мудрую идею. Должен ли я просто сдаться и попытаться, если производительность действительно слишком плохая, может быть?

Ответы [ 3 ]

2 голосов
/ 07 декабря 2011

Замена системного open() вызова - потенциально плохая вещь.Требуется, чтобы все, что использует open(), использовали его так, как вы ожидаете.

Почему вы хотите избежать изменения кода?

Да, измерьте производительность и посмотрите, стоит ли это.Например, вставьте приведенный выше код и посмотрите, насколько быстрее все происходит.Если это только на 1% быстрее, то нет никаких оснований что-либо делать.Если это значительно быстрее, посмотрите, что использует open() и измените этот код, если можете.

Кстати, что-то вроде LRU-кеша (часть functools в Python 3.2) также будет полезно для вашей задачи.

2 голосов
/ 07 декабря 2011

вы можете использовать mmap модуль: http://docs.python.org/library/mmap.html

1 голос
/ 07 декабря 2011

Я не уверен, что функциональность, предлагаемая этой библиотекой, имеет какое-либо применение в вашем сценарии, но, тем не менее, следует упомянуть о существовании linecache библиотеки .Из связанных документов:

Модуль linecache позволяет получить любую строку из любого файла, одновременно пытаясь внутренне оптимизировать, используя кэш, общий случай, когда многие строки читаются из одного файла.

... конечно, это даже близко не подходит к вашей проблеме реализации решения элегантным и прозрачным способом ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...