From 864be716673b882aeea7e5f8266992c31f7014e5 Mon Sep 17 00:00:00 2001 From: Nicolas F Date: Thu, 4 Jul 2019 16:40:11 +0200 Subject: [PATCH] textures: cache when a texture couldn't be found Previously, textures that couldn't be found the first time around would not have this fact cached, so we'd run through the whole slow path of find_file with each blockid and data entry. This is what caused the chests texture generation function to take almost 12 seconds on my system, as it is looking for "normal.png" that hasn't existed in Minecraft textures for ages. Shoving the exception, if one is encountered, into the cache, and then re-raising it if we load it from the texture cache brings this number down to about 2 seconds. That's six times as fast! Concerns issue #1604. --- overviewer_core/textures.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 160579f..6da4402 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -357,10 +357,21 @@ class Textures(object): def load_image(self, filename): """Returns an image object""" - if filename in self.texture_cache: - return self.texture_cache[filename] + try: + img = self.texture_cache[filename] + if isinstance(img, Exception): # Did we cache an exception? + raise img # Okay then, raise it. + return img + except KeyError: + pass - fileobj = self.find_file(filename) + try: + fileobj = self.find_file(filename) + except (TextureException, IOError) as e: + # We cache when our good friend find_file can't find + # a texture, so that we do not repeatedly search for it. + self.texture_cache[filename] = e + raise e buffer = BytesIO(fileobj.read()) img = Image.open(buffer).convert("RGBA") self.texture_cache[filename] = img