Python 这段代码性能差,如何使它更好?
我正在尝试为一个学校项目建立一个推荐算法。在某种程度上,我有这个函数,它对性能至关重要。它返回与用户具有最高相似性的5个项目。我用了三种不同的方法 (1) ,我认为这是最“python”的方法,但却是最慢的方法,大约需要800毫秒才能完成 (2) 虽然它增加了一个排序操作,但速度要快得多(600毫秒)Python 这段代码性能差,如何使它更好?,python,performance,python-3.x,numpy,cython,Python,Performance,Python 3.x,Numpy,Cython,我正在尝试为一个学校项目建立一个推荐算法。在某种程度上,我有这个函数,它对性能至关重要。它返回与用户具有最高相似性的5个项目。我用了三种不同的方法 (1) ,我认为这是最“python”的方法,但却是最慢的方法,大约需要800毫秒才能完成 (2) 虽然它增加了一个排序操作,但速度要快得多(600毫秒) 那么,我就做了,就像我在旧学校C++(3)中那样做,这是最快的,但不是很多(550MS): 但这仍然比(3)慢一些(580ms) 是否值得在cython中编译(3)或useritem\u相似性?
那么,我就做了,就像我在旧学校C++(3)中那样做,这是最快的,但不是很多(550MS):
但这仍然比(3)慢一些(580ms)- 是否值得在cython中编译(3)或
useritem\u相似性
?它会产生更好的性能吗
- 我有一个建议,不能在评论的约束范围内制定
我认为你做得太过分了,你可以保持最好的5个结果,就像我构建的这个例子一样
In [1]: import bisect as bs
In [2]: from random import random, seed
In [3]: seed(8888)
In [4]: l = [random() for _ in range(100)]
In [5]: r = [0 for i in range(5)]
In [6]: for x in l:
...: if x>r[0]:
...: bs.insort(r, x)
...: r.pop(0)
...:
In [7]: print(r) ; print(sorted(l)[-5:])
[0.9734802621456982, 0.9764741228388244, 0.9806769811156987, 0.9820424903993659, 0.9884636482746705]
[0.9734802621456982, 0.9764741228388244, 0.9806769811156987, 0.9820424903993659, 0.9884636482746705]
In [8]:
当然,您应该使这个简单的示例适应您更复杂的用例,但是避免移动大量数据(插入和/或排序)可能会有很大帮助
另一种可能性是
继续使用heapq
模块提供的可能性
In [10]: from heapq import nlargest
In [11]: nlargest(5, l)
Out[11]:
[0.9884636482746705,
0.9820424903993659,
0.9806769811156987,
0.9764741228388244,
0.9734802621456982]
(顺序颠倒了)
虽然heapreplace
的计时略好于的计时,但nlargest
的计时速度明显更快
我不引用时间,因为您必须根据数据对不同的可能性进行基准测试,请记住,存储所有结果并最终排序的方法可能比上述方法更快,具体取决于您处理的数据量,正如我在一篇评论中提到的。既然您已经有了几种算法可以执行您需要的功能,现在您可以对它们进行基准测试/计时,从而找到性能最好的算法
然后,您将分析获胜的代码,以找到其瓶颈所在
然后,您将使用我提到的技术/工具来消除这些瓶颈
我详细介绍了上面的每一项,包括在中检查了每一项的工具。您能创建一个演示如何调用这些函数的工具吗?我已经使用Jupyter中的%timeit
和同一个用户对它们进行了基准测试。这就是你要问的吗?无论如何,它们将在这个循环中被调用:feature\u recommendations\u dict={user:get\u item\u similarfeaturesN(user)for user in target\u users\u list}
我们需要能够自己运行这个代码来提供帮助。向我们展示如何运行它,以及您输入的数据类型。一个完全独立的程序(完整)。这个问题比这个网站更适合。我希望这是你的意思。我做了一些测试,发现对于较长的序列,insort()
轻而易举地获胜,对于较短的序列,收集所有结果并最终对整个结果序列排序更快。-您最好根据您的应用程序域的数据大小特点,选择不同的算法(比如我的算法和您的算法2)。再见
In [1]: import bisect as bs
In [2]: from random import random, seed
In [3]: seed(8888)
In [4]: l = [random() for _ in range(100)]
In [5]: r = [0 for i in range(5)]
In [6]: for x in l:
...: if x>r[0]:
...: bs.insort(r, x)
...: r.pop(0)
...:
In [7]: print(r) ; print(sorted(l)[-5:])
[0.9734802621456982, 0.9764741228388244, 0.9806769811156987, 0.9820424903993659, 0.9884636482746705]
[0.9734802621456982, 0.9764741228388244, 0.9806769811156987, 0.9820424903993659, 0.9884636482746705]
In [8]:
In [1]: from random import random, seed
In [2]: from heapq import heappushpop, heapreplace
In [3]: seed(8888)
In [4]: l = [random() for _ in range(100)]
In [5]: r = [0 for i in range(5)]
In [6]: for x in l:
...: if x>r[0]: heapreplace(r, x)
In [7]: r
Out[7]:
[0.9734802621456982,
0.9764741228388244,
0.9806769811156987,
0.9820424903993659,
0.9884636482746705]
In [8]:
In [10]: from heapq import nlargest
In [11]: nlargest(5, l)
Out[11]:
[0.9884636482746705,
0.9820424903993659,
0.9806769811156987,
0.9764741228388244,
0.9734802621456982]