这个名为svnmerge.py的脚本正在尝试调整和优化。我对Python完全不熟悉,所以这并不容易。
当前问题似乎与脚本中名为RevisionSet
的类有关。实质上它所做的是创建一个整数键布尔值的大散列表(?)。在最坏的情况下 - 我们的SVN存储库中的每个版本都有一个,现在接近75,000。
之后,它对如此庞大的数组执行集合操作 - 加法,减法,交集等。实现是最简单的O(n)实现,当然,在这么大的集合上变得非常慢。整个数据结构可以优化,因为有很长的连续值。例如,1到74,000之间的所有键可能包含true
。此脚本也是为Python 2.2编写的,这是一个非常古老的版本,我们无论如何都使用2.6,所以也可能有一些东西可以获得。
我可以尝试自己拼凑这些,但这很困难并且需要花费很多时间 - 更不用说它可能已经在某处实现了。虽然我喜欢学习经历,但结果现在更重要。你有什么建议我做的?
答案 0 :(得分:7)
您可以尝试使用numpy而不是普通的python。对于像这样的操作,我发现它非常。
例如:
# Create 1000000 numbers between 0 and 1000, takes 21ms
x = numpy.random.randint(0, 1000, 1000000)
# Get all items that are larger than 500, takes 2.58ms
y = x > 500
# Add 10 to those items, takes 26.1ms
x[y] += 10
由于这有很多行,我认为75000不应该是一个问题:)
答案 1 :(得分:1)
这是RevisionSet的快速替代品,使其成为一个集合。它应该快得多。我没有完全测试它,但它适用于我所做的所有测试。毫无疑问,其他方法可以加快速度,但我认为这确实会有所帮助,因为它实际上利用了集合的快速实现,而不是在Python中执行循环,原始代码在__sub__
和{{等函数中执行1}}。唯一的问题是迭代器没有排序。您可能需要更改一些代码来解决这个问题。我相信还有其他方法可以改善这一点,但希望它会给你一个良好的开端。
__and__
<强>增加:强> 顺便说一句,我比较了原始RevisionSet和上面的RevisionSet的联合,交叉和减法,并且当在具有75000个元素的两个RevisionSets上运行时,上述代码的运行速度提高了3倍到7倍。我知道其他人都说numpy是要走的路,但是如果你对Python不是很有经验,正如你的评论所指出的那样,那么你可能不想去那条路,因为它会涉及更多的变化。我建议尝试我的代码,看看它是否有效,如果有效,那么看看它是否足够快。如果不是,那么我会尝试分析以查看需要改进的内容。只有这样我才会考虑使用numpy(这是我经常使用的一个很好的包)。
答案 2 :(得分:0)
例如,1到74,000之间的所有键都包含true
为什么不在子集上工作?到目前为止只有74001。
修剪74/75的数据比尝试编写比 O (n)更聪明的算法容易得多。
答案 3 :(得分:0)
您应该重写RevisionSet以获得一组修订。我认为修订的内部表示应该是一个整数,并且应该根据需要创建修订范围。
没有令人信服的理由使用支持python 2.3及更早版本的代码。
答案 4 :(得分:0)
只是一个想法。我曾经在二进制图像处理中使用运行编码来做这种事情。也就是说,将每个集合存储为一系列数字:关闭位数,打开位数,关闭位数等。
然后,您可以对它们进行各种布尔运算,作为简单合并算法的装饰。