关于nltk:如何在每次重新加载python模块时避免计算 您所在的位置:网站首页 csgo重新加载代码 关于nltk:如何在每次重新加载python模块时避免计算

关于nltk:如何在每次重新加载python模块时避免计算

2023-02-22 21:25| 来源: 网络整理| 查看: 265

我有一个使用巨大字典全局变量的python模块,当前我将计算代码放在顶部,每次模块的第一次导入或重新加载都花费一分钟以上的时间,这是完全不可接受的。如何将计算结果保存在某处,以便下次导入/重新加载不必计算它?我尝试了cPickle,但是从文件(1.3M)加载字典变量大约需要与计算相同的时间。

要提供有关我的问题的更多信息,

1FD = FreqDist(word for word in brown.words()) # this line of code takes 1 min 相关讨论 您能否澄清一下:您是否需要在不同的Python解释器调用之间保持持久性,还是要询问同一解释器实例中的多个导入? 我同意以下提示,但是您真的应该提供有关数据类型,如何产生数据以及它们用于什么目的(目的和过程)的更多详细信息,因为正确的解决方案在很大程度上取决于此。 我已经在上面添加了代码行。

只需澄清一下:每次导入模块时,模块主体中的代码都不会执行-它仅运行一次,此后将来的导入将查找已创建的模块,而不是重新创建它。查看sys.modules以查看缓存的模块列表。

但是,如果您的问题是程序运行后第一次导入所花费的时间,则可能需要使用除python dict以外的其他方法。最好的办法是使用磁盘上的表单,例如sqlite数据库,即dbm模块之一。

对于您的界面进行最小的更改,最好使用shelve模块-在dbm模块之间放置一个相当透明的接口,使它们像任意python dict一样工作,从而允许存储任何可拾取的值。这是一个示例:

12345# Create dict with a million items: import shelve d = shelve.open('path/to/my_persistant_dict') d.update(('key%d' % x, x) for x in xrange(1000000)) d.close()

然后在下一步中使用它。应该没有大的延迟,因为仅对磁盘上请求的键执行查找,因此不必将所有内容都加载到内存中:

123>>> d = shelve.open('path/to/my_persistant_dict') >>> print d['key99999'] 99999

这比实际命令要慢一些,如果您执行需要所有键的操作(例如尝试打印它),但仍会花费很长时间来加载,但可能会解决您的问题。

在首次使用时计算全局变量。

12345678class Proxy:     @property     def global_name(self):         # calculate your global var here, enable cache if needed         ... _proxy_object = Proxy() GLOBAL_NAME = _proxy_object.global_name

或者更好的是,通过特殊的数据对象访问必需品数据。

1234class Data:     GLOBAL_NAME = property(...) data = Data()

示例:

123from some_module import data print(data.GLOBAL_NAME)

请参阅Django设置。

对于大型数据集,

shelve变得非常慢。我一直很成功地使用redis,并围绕它编写了FreqDist包装器。它非常快,可以同时访问。

如果"搁置"解决方案变得太慢或太慢,则还有其他可能性:

推 杜鲁斯 ZopeDB pyTables

您可以尝试使用marshal模块而不是c?Pickle模块;它可能会更快。 python使用此模块以二进制格式存储值。请特别注意以下段落,以了解元帅是否符合您的需求:

Not all Python object types are supported; in general, only objects whose value is independent from a particular invocation of Python can be written and read by this module. The following types are supported: None, integers, long integers, floating point numbers, strings, Unicode objects, tuples, lists, sets, dictionaries, and code objects, where it should be understood that tuples, lists and dictionaries are only supported as long as the values contained therein are themselves supported; and recursive lists and dictionaries should not be written (they will cause infinite loops).

出于安全考虑,在解组该dict之前,请确保解组该dict的Python版本与执行该命令的python版本相同,因为不能保证向后兼容。

我假设您已将dict文字粘贴到源代码中,这需要一分钟吗?我不知道该如何解决,但是您可能可以避免在导入时实例化此命令……您可以在第一次实际使用它时对其进行惰性化。

相关讨论 FD = FreqDist(以单词为单位的单词brown.words())#这行代码需要一分钟 如果FD每次都相同,则将" print FD"的结果直接粘贴到源文件中,然后跳过计算步骤。 FD是一个巨大的第三方类实例,不能以文字形式编写。

我正在经历同样的问题... 搁置,数据库等...对于此类问题都太慢了。您需要进行一次点击,将其插入到Redis等内存密钥/ val存储中。它只会驻留在内存中(警告它可能会占用大量内存,因此您可能需要专用的盒子)。您将不必重新加载它,而只需在内存中寻找键

1234r = Redis() r.set(key, word) word = r.get(key)

将需要大量计算的部分分解到一个单独的模块中。然后至少在重新加载时,您无需等待。

尝试使用协议2转储数据结构。要尝试的命令为cPickle.dump(FD, protocol=2)。从cPickle.Pickler:

的文档字符串

12345Protocol 0 is the only protocol that can be written to a file opened in text mode and read back successfully.  When using a protocol higher than 0, make sure the file is opened in binary mode, both when pickling and unpickling. 相关讨论 似乎将代码放在单独的模块中并没有太大帮助,当重新加载该模块时,再次执行单独模块中的代码。

几项有助于加快进口速度的事情:

您可以在运行python时尝试使用-OO标志运行python。这将进行一些优化,从而减少模块的导入时间。 有什么原因不能将字典分解成可以更快加载的单独模块中的较小词典? 作为最后的选择,您可以异步进行计算,以便它们不会延迟您的程序,直到需要结果为止。或者,如果您想利用多核体系结构,甚至可以将字典放在一个单独的进程中,并使用IPC来回传递数据。

话虽如此,我同意您在首次导入模块后不应再经历任何延迟。以下是一些其他一般想法:

您要在函数中导入模块吗?如果是这样,这可能会导致性能问题,因为它必须在每次命中import语句时检查并查看模块是否已加载。 您的程序是多线程的吗?我曾见过这样的情况:在多线程应用程序中,在模块导入时执行代码可能会引起一些混乱和应用程序不稳定(最明显的是cgitb模块)。 如果这是全局变量,请注意,全局变量查找时间可能比本地变量查找时间长得多。在这种情况下,如果您在同一上下文中多次使用字典,则可以通过将字典绑定到局部变量来显着提高性能。

话虽如此,在没有更多上下文的情况下为您提供任何具体建议有点困难。更具体地说,您要将其导入哪里?什么是计算?

您可以使用搁板将数据存储在光盘上,而不是将整个数据加载到内存中。因此,启动时间将非常快,但是权衡将使访问时间变慢。

Shelve也将使dict值腌制,但不会在启动时对所有项目都进行腌制,而只会在每个项目本身访问时进行。

还有另一个很明显的解决方案。重新加载代码后,原始范围仍然可用。

因此...执行类似的操作将确保该代码仅执行一次。

1234try:     FD except NameError:     FD = FreqDist(word for word in brown.words())

或者您可以只使用数据库来存储值?检出SQLObject,这使将内容存储到数据库非常容易。

扩展延迟计算的思想,为什么不将dict变成一个根据需要提供(和缓存)元素的类?

您也可以使用psyco来加快整体执行速度...

相关讨论 您也可以查看pyrex / cython。 psyco似乎仍然只能在32位系统上运行



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有