计算有和没有SciPy的k组合的数量

Ari*_*ide 6 python benchmarking combinations scipy

令我感到困惑的是,combSciPy的功能似乎比天真的Python实现慢.这是解决欧拉项目问题53的两个等效程序的测量时间.


使用SciPy:

%%timeit
from scipy.misc import comb

result = 0
for n in range(1, 101):
    for k in range(1, n + 1):
        if comb(n, k) > 1000000:
            result += 1
result
Run Code Online (Sandbox Code Playgroud)

输出:

1 loops, best of 3: 483 ms per loop
Run Code Online (Sandbox Code Playgroud)

没有SciPy:

%%timeit
from math import factorial

def comb(n, k):
    return factorial(n) / factorial(k) / factorial(n - k)

result = 0
for n in range(1, 101):
    for k in range(1, n + 1):
        if comb(n, k) > 1000000:
            result += 1
result
Run Code Online (Sandbox Code Playgroud)

输出:

10 loops, best of 3: 86.9 ms per loop
Run Code Online (Sandbox Code Playgroud)

第二个版本大约快5倍(在两台Mac上测试,python-2.7.9-1,IPython 2.3.1-py27_0).这是combSciPy功能的预期行为(源代码)吗?我究竟做错了什么?


编辑(来自Anaconda 3.7.3-py27_0发行版的SciPy):

import scipy; print scipy.version.version
0.12.0
Run Code Online (Sandbox Code Playgroud)

编辑(IPython以外的相同区别):

$ time python with_scipy.py
real    0m0.700s
user    0m0.610s
sys     0m0.069s

$ time python without_scipy.py
real    0m0.134s
user    0m0.099s
sys     0m0.015s
Run Code Online (Sandbox Code Playgroud)

Hoo*_*ked 7

看起来您可能正在错误地运行计时并测量加载scipy到内存中所需的时间.当我跑:

import timeit
from scipy.misc import comb
from math import factorial

def comb2(n, k):
    return factorial(n) / factorial(k) / factorial(n - k)

def test():
    result = 0
    for n in range(1, 101):
        for k in range(1, n + 1):
            if comb(n, k) > 1000000:
                result += 1

def test2():
    result = 0
    for n in range(1, 101):
        for k in range(1, n + 1):
            if comb2(n, k) > 1000000:
                result += 1

T = timeit.Timer(test)
print T.repeat(3,50)

T2 = timeit.Timer(test2)
print T2.repeat(3,50)
Run Code Online (Sandbox Code Playgroud)

我明白了:

[2.2370951175689697, 2.2209839820861816, 2.2142510414123535]
[2.136591911315918, 2.138144016265869, 2.1437559127807617]
Run Code Online (Sandbox Code Playgroud)

这表明scipy 比python版本略.


Ari*_*ide 4

回答我自己的问题。似乎SciPy 中同一事物存在两个不同的函数。我不太清楚为什么。但另外一个 ,binom比 快 8.5 倍comb,比我的快 1.5 倍,这让人放心:

%%timeit
from scipy.special import binom
result = 0
for n in range(1, 101):
    for k in range(1, n + 1):
        if binom(n, k) > 1000000:
            result += 1
result
Run Code Online (Sandbox Code Playgroud)

输出:

10 loops, best of 3: 56.3 ms per loop
Run Code Online (Sandbox Code Playgroud)

SciPy 0.14.0 的朋友们,这对你们也有用吗?