speed up b64suffix by using a simple array lookup instead of base64.b64encode

This commit is contained in:
Jan Petykiewicz 2024-07-29 11:30:31 -07:00
parent da7118f521
commit a8a42bba1d

View File

@ -17,14 +17,11 @@ Classes include:
from typing import Self, TYPE_CHECKING, cast, TypeAlias, Protocol, Literal from typing import Self, TYPE_CHECKING, cast, TypeAlias, Protocol, Literal
from collections.abc import Iterator, Mapping, MutableMapping, Sequence, Callable from collections.abc import Iterator, Mapping, MutableMapping, Sequence, Callable
import logging import logging
import base64
import struct
import re import re
import copy import copy
from pprint import pformat from pprint import pformat
from collections import defaultdict from collections import defaultdict
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from functools import lru_cache
import numpy import numpy
from numpy.typing import ArrayLike, NDArray from numpy.typing import ArrayLike, NDArray
@ -349,8 +346,11 @@ class ILibraryView(Mapping[str, 'Pattern'], metaclass=ABCMeta):
else: else:
sanitized_name = name sanitized_name = name
ii = 0
suffixed_name = sanitized_name suffixed_name = sanitized_name
if sanitized_name in self:
ii = sum(1 for nn in self.keys() if nn.startswith(sanitized_name))
else:
ii = 0
while suffixed_name in self or suffixed_name == '': while suffixed_name in self or suffixed_name == '':
suffixed_name = sanitized_name + b64suffix(ii) suffixed_name = sanitized_name + b64suffix(ii)
ii += 1 ii += 1
@ -1229,8 +1229,18 @@ class AbstractView(Mapping[str, Abstract]):
return self.library.__len__() return self.library.__len__()
@lru_cache(maxsize=8_000)
def b64suffix(ii: int) -> str: def b64suffix(ii: int) -> str:
"""Turn an integer into a base64-equivalent suffix.""" """
suffix = base64.b64encode(struct.pack('>Q', ii), altchars=b'$?').decode('ASCII') Turn an integer into a base64-equivalent suffix.
return '$' + suffix[:-1].lstrip('A')
This could be done with base64.b64encode, but this way is faster for many small `ii`.
"""
def i2a(nn: int) -> str:
return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$?'[nn]
parts = ['$', i2a(ii % 64)]
ii >>= 6
while ii:
parts.append(i2a(ii % 64))
ii >>= 6
return ''.join(parts)