【发布时间】:2011-07-13 05:09:59
【问题描述】:
我有一些遗留的 python 代码,它们使用 pypar 和 mpich2 在多个节点之间传输数据。出于某种原因,数据保存在架子上,pypar 想要腌制架子以将其发送到其他节点。不允许酸洗货架。所以我想从搁置转换为我可以通过 pypar 发送的东西,它在发送到其他节点之前对其进行腌制。有什么建议?我可以将搁置转换为 json 并腌制吗?
【问题讨论】:
标签: python json pickle mpi shelve
我有一些遗留的 python 代码,它们使用 pypar 和 mpich2 在多个节点之间传输数据。出于某种原因,数据保存在架子上,pypar 想要腌制架子以将其发送到其他节点。不允许酸洗货架。所以我想从搁置转换为我可以通过 pypar 发送的东西,它在发送到其他节点之前对其进行腌制。有什么建议?我可以将搁置转换为 json 并腌制吗?
【问题讨论】:
标签: python json pickle mpi shelve
尝试将搁置转换为dict(),然后对其进行酸洗:
sdb = shelve.open('foo.db')
sdb['abc'] = {'a': 1, 'b': 2}
tmp = cPickle.dumps(dict(sdb), 2)
print cPickle.loads(tmp)
{'abc': {'a': 1, 'b': 2}}
更新:(对 cmets 中的问题的回应):dict 可以从任何映射对象复制键值,因此如果该对象实现了方法 keys 和 __getitem__它会起作用的。由于搁置是一个映射对象,dict 复制构造函数可以从搁置中读取键值,然后您可以腌制得到的 dict 并将其发送到其他主机。
以下示例显示了复制对象所需的最小接口dict:
class Foo(object):
def __init__(self):
self.value = 0
def keys(self):
return ['a', 'b']
def __getitem__(self, key):
v = self.value
self.value += 1
return self.value
foo = Foo()
print dict(foo)
print dict(foo)
输出
{'a': 1, 'b': 2}
{'a': 3, 'b': 4}
更新:要将字典的内容添加回搁置,请使用update():
d = {'a': 1, 'b': 2}
s = shelve.open('foo.db')
s.update(d)
print s
{'a': 1, 'b': 2}
【讨论】:
shelve 是一个 DictMixin,这意味着它的行为就像一个 dict,因此可以将它传递给 dict 的构造函数,该构造函数将复制其内容。我将更新我的答案,提供更多说明。
@samplebias's suggestion 将您的搁置对象转换为字典将起作用。
但是,(这可能是一个长镜头,但是)考虑到您的数据已经搁置到一个 db 文件中,可能值得检查让其他节点从数据库中加载数据是否更快搁置文件而不是进行 MPI 发送。我假设所有节点都可以访问同一个文件系统,因为您使用 MPI 运行它们。
老实说,我希望 MPI 发送速度更快,特别是如果您在共享内存系统上运行,因为许多 MPI 实现将回退到内存副本。但是,一旦您将发送的重新酸洗和取消酸洗的开销包括在内,比赛可能会很接近!
我怀疑这将取决于您运行它的节点数量以及您的通信模式。
【讨论】: