我正在构建一个类来处理基于字符串输入的绘图。我希望能够将图形输出到png和svg图像。我处理输入模式以创建将用于构造两种输出格式的图形的抽象。
这个抽象是一个定义形状的对象数组,它将由两个独立的方法迭代,一个使用我们的数据来构建svg元素,使用我为任务编写的自定义模块,另一个使用{{1} }库创建输出到png的形状。这两种方法都没有问题,代码都正常工作,我的输出是预期的。
我的问题是效率问题,因为此代码将在服务器上运行,并将用于从API返回图像数据。目前我的代码结构如下:
PIL
每个渲染方法都有单独的依赖;必须加载以执行绘图的库。对于任何给定的API响应,只会调用一个呈现方法,因此我希望每次class Pattern:
def __init__(self, input_pattern):
self.pattern = input_pattern
self.data = self.__process()
def __process(self):
# processes the input, returning an array
# of custom shape objects
# which will be read by the render methods
def renderSVG(self):
# uses self.data to render an svg
def renderPNG(self):
# uses self.data to render a png
实例化时都避免为其他方法加载依赖项。
我想到了两种可能的解决方案:
解决方案1。在渲染方法中导入库。
例如:
Pattern
这是否气馁?我总是在文件的顶部导入模块,而不是在其中。看起来这样可行,但我想知道是否有充分的理由避免这样做,因为我很少看到它。
解决方案2. 为不同格式制作子类。
例如,从基类中删除两个render方法,并在单独的文件中删除:class Pattern:
# initialization etc...
def renderPNG:
import PIL
# use PIL to render png
这也可以,但是像这样的子类化的成本是多少?处理from theModuleDescribedAbove import Pattern
import PIL
class PNGPattern(Pattern):
def __init__(self, input_pattern):
Pattern.__init__(self, input_pattern)
def render(self):
# use PIL to render png
类中的输入的代码比任何一种渲染方法都要长,但不如Pattern
模块大。它必须在可以使用之前导入,与在解决方案1中使用的文件相比,它是否会显着减慢速度?
哪种方法可能效率最高?有没有更好的方法,我没有想到?任何建议或意见将不胜感激。
答案 0 :(得分:3)
如果这是服务器上的API,可能它是Web框架的一部分,并通过WSGI提供服务。在这种情况下,您认为为每个请求加载依赖项是错误的。它们不是:一个进程被实例化以处理请求,并且将持续存在许多请求。在该过程中,一旦导入模块,它们将保留在内存中:后续导入语句不导致代码再次加载。
因此,总而言之,您不必要地担心,这不是效率低下的原因。
答案 1 :(得分:1)
使用内联导入模块的解决方案应该没问题。没有与此相关的任何性能损失。遇到import语句时,python会执行引用的模块中的所有顶级代码。完成此操作后,它会将模块缓存在标准库变量sys.modules
中。随后,从sys.modules
检索模块,而不是重新解析/重新执行。为了清晰起见,人们倾向于支持文件顶部的导入。它使人们更容易阅读代码,以确切了解给定文件中正在使用的模块。作为旁注,使用本地导入可以更快,因为python中的局部变量比全局变量检索得更快。
正如Daniel所说,WSGI应用程序往往由许多进程提供服务,这些进程由Gunicorn或Uwsgi等应用程序服务器预先提供。只要进程继续运行,它们就会累积已在sys.modules
中导入的任何模块。这些模块不会缓存在sys.modules
中,直到它们被进程的启动代码或处理请求时执行的视图代码导入。