From cc30df8706a9ee47c0d88342da4de624fc7c68cc Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Fri, 27 May 2022 18:41:17 -0700 Subject: [PATCH] Move markov nodes to be single strings Separating strings by spaces is more memory-friendly than using tuples. Signed-off-by: Alek Ratzloff --- plugins/markov.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/plugins/markov.py b/plugins/markov.py index ebb7be5..eb707ba 100644 --- a/plugins/markov.py +++ b/plugins/markov.py @@ -21,7 +21,7 @@ def chain_inner_default() -> defaultdict[str | None, int]: return defaultdict(int) -def chain_default() -> defaultdict[tuple[str, ...], defaultdict[str | None, int]]: +def chain_default() -> defaultdict[str, defaultdict[str | None, int]]: return defaultdict(chain_inner_default) @@ -51,11 +51,11 @@ class Chain: return self.__load() for fragment in windows(parts + [None], self.order + 1): - head = tuple(fragment[0:-1]) + head = fragment[0:-1] tail = fragment[-1] - self.__cache[head][tail] += 1 + self.__cache[" ".join(head)][tail] += 1 - def get(self, key: tuple[str, ...]) -> dict[str | None, int]: + def get(self, key: str) -> dict[str | None, int]: self.__last_access = asyncio.get_running_loop().time() if self.__cache: if key in self.__cache: @@ -67,7 +67,7 @@ class Chain: self.__load() return self.__cache[key] - def set(self, key: tuple[str, ...], value: Mapping[str | None, int]): + def set(self, key: str, value: Mapping[str | None, int]): self.__last_access = asyncio.get_running_loop().time() if not self.__cache: # Attempt the cache before writing to it @@ -85,7 +85,7 @@ class Chain: self.__cache = defaultdict( chain_inner_default, { - tuple(key.split(" ")): defaultdict( + key: defaultdict( int, { (None if not word else word): weight @@ -107,7 +107,7 @@ class Chain: with open(self.path, "w") as fp: json.dump( { - " ".join(key): { + key: { ("" if word is None else word): weight for word, weight in value.items() } @@ -131,17 +131,16 @@ class Chain: words: List[str] = [] - node = random.choice(list(self.__cache.keys())) + node = random.choice(list(self.__cache.keys())).split(" ") words += node - next: str | None = self.choose_next(node) + next: str | None = self.choose_next(" ".join(node)) while next: words += [next] - node = (*node[1:], next) - next = self.choose_next(node) - + node = [*node[1:], next] + next = self.choose_next(" ".join(node)) return " ".join(words) - def choose_next(self, head: tuple[str, ...]) -> str | None: + def choose_next(self, head: str) -> str | None: self.__load() choices = self.__cache[head] words = list(choices.keys())