底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

人工智能浪潮之下,学习 Python 成为必然趋势。Python 以简单的语法、良好的交互性、移植性等优势受到开发者的喜爱,但和老牌的 C++ 相较而言,谁运行的速度更快一些?开发者会毫无疑问地选择了 C++,而本文也证实了这一点。(私信小编007获取大量Python学习资源!)

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

算法

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

但在比较歌曲时还需要考虑更多情况。有时两首歌开头的空白时间长短不同,因此指纹的比特不会完美地对齐,直接比较会不匹配,但将其中一个指纹移动一位可能就能匹配。

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

最初的 Python 实现

Bard 是用 Python 写的,所以第一版实现采用了 Python 的列表以整数数组的方式保存指纹。每次迭代过程中需要移位时,我会在其中一个指纹数组前面加个 0,然后迭代整个数组,依次比较每个元素。比较的方法是对两个元素执行异或操作,然后用一个算法来数出整数中的比特个数:

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

我们把这个实现的速度作为参考值,称之为一倍速。

第一个改进

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

这个改进使得比较速度几乎提高到了两倍速。

使用 C++17

此时,我认为这段代码没办法很容易扩展到更大的曲库上,因此我认为 Bard 需要更好的实现。修改内存很慢,而 C/C++ 可以实现更细粒度的底层优化,但我并不想用 C++ 重写整个应用,因此我采用了

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

这个算法最大的好处就是比较过程不会修改或复制任何指纹,这使得速度增加了 126.47 倍。此时我开始计算另一个度量:每秒钟比较的歌曲数(别忘了每比较一对歌曲就要做 200 次指纹比较)。这个算法的平均速度是 580 首/秒。或者换句话说,要想比较 1000 首歌,需要花费大约 14 分 22 秒(注意原来的 Python 实现大约需要一天 6 小时 16 分 57 秒)。

首次并行算法尝试

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

这个方法能把速度提高到 1897 倍,或者说大约 8700 首歌曲/秒(1000 首歌曲需要处理大约57秒。很不错,是吧!)

第二次并行尝试

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

很显然我却忘记了的重要改进

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

免费得到的 Tumbleweed 的改进

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

最终的优化

底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!

结论

从这次经历中得到的一些值得记录的经验:

  • 花点时间优化代码,会物有所值。
底层语言C++ 帮高级语言 python 代码实现 10000 倍加速!



分享到:


相關文章: