быстро ха sh любых данных в python - PullRequest
0 голосов
/ 07 марта 2020

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

Простой пример:

import hashlib

class Base():
    def compute(self, *args):
        raise NotImplementedError

    def compute_with_cache(self, *args):
        hash_ = self._hash_anything(args)
        try:
            return self.cache[hash_]
        except KeyError:
            result = self.compute(*args)
            self.cache[hash_] = result
            return result

    @staticmethod
    def _hash_anything(args):
        return hashlib.md5(str(args).encode('utf-8')).hexdigest()

class SpecificComputation(Base):
    cache = {}
    def compute(self, some_arg, other_arg):
        result = ... # performs possibly time consuming operations
        return result

Это решение почему-то работает, но имеет два (может быть, больше? ) проблемы:

  1. Предполагается, что str(args) отличается для каждого различного набора args, это обычно справедливо для простых структур данных, таких как списки или числа, но завершится ошибкой, например, для экземпляров классов без Однозначные строковые представления
  2. Требуется приведение к строке и вычисление md5, и это занимает время

Первая проблема может быть решена с помощью pickle, но она замедлится еще больше.

Итак, вопрос в том, как реализовать _hash_anything таким образом, чтобы:

  • был неуязвим для проблемы, описанной в 1
  • , будет максимально быстро

    ?

Есть ли какое-либо общее решение, предполагающее, что args может содержать практически что-нибудь?

Если нет, возможно, существует эффективный при условии решения args содержат только простые структуры данных (кортежи целых чисел, списки строк и т. Д. c) или np.arrays?

...