Python整数比较(不等于0)基准

2024-05-26 20:45:45 发布

您现在位置:Python中文网/ 问答频道 /正文

为了好玩,我用python做了一个2D物理引擎。我用物体的速度来决定是否应该对它进行碰撞检测。也就是说,如果它的速度会导致它在下一个循环中进入另一个物体,那么我就对它进行碰撞检测。你知道吗

注意:x和y速度总是整数

所以我意识到我必须检查物体的x或y速度是否小于或大于(不是)0。你知道吗

有很多方法可以做到这一点。我想出了4种不同的方法:

def cmp1 (a,b):
    return a > 0 or a < 0 or b > 0 or b < 0

def cmp2 (a, b):
    return a != 0 or b != 0

def cmp3 (a, b):
    return abs(a | b) > 0

def cmp4 (a, b):
    return a | b != 0

我喜欢第四种方法,因为它的运算最少,而且英语读起来也很好 a or b does not equal 0

但是在我使用的4种方法和基准测试方法中,它的平均时间是第二慢的,这让我很惊讶。事实上,第一种方法是最快的(同样,使用我使用的基准测试方法)。你知道吗

下面是我用来计算时间的方法:

def randints(min, max, amount):
    return tuple([random.randint(min, max) for i in range(amount)])

times = []
for i in range(1000):
    n = randints(-9999, 9999, 2)
    t = time.time() * 1000
    cmp4(*n)
    t2 = time.time() * 1000
    times.append(t2-t)

print('Average Time: ', sum(times)/len(times))

如果我对每个方法运行多次,我会得到非常一致的结果:

cmp1-0.00027秒

cmp2-0.00032秒

cmp3-0.00037秒

cmp4-0.00035s

所以我的问题是,为什么第四种方法比第一种慢?2次运算(一次按位,一次比较)肯定要比4次快。你知道吗

是的,我知道只有几微秒的差别。你知道吗


Tags: or方法returntimedef时间基准速度
1条回答
网友
1楼 · 发布于 2024-05-26 20:45:45

有更好的测试方法

y = [(random.randint(0,1), random.randint(0,1)) for _ in range(100_000)]

def test(cmp):
    [cmp(a, b) for a, b in y]

%timeit test(cmp1)
20.1 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit test(cmp2)
17.3 ms ± 212 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit test(cmp3)
29.3 ms ± 588 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit test(cmp4)
21.9 ms ± 289 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

or的主要优点是短路,实际上相当于:

def or(a, b):
    if a: return a
    return b

然而|需要执行一个实际的(非常低级的)操作,然后创建一个新的python integer对象,然后执行另一个操作。你知道吗

我的测试使用一个50%为零的数组。如果有一个较大或较小的百分比的零的结果可能会有很大的不同。你知道吗

在任何情况下,您都忘记了最快的方法(因为所有非零数都是True):

def cmp0(a, b):
    return a or b

bool(cmp0(0, 0)), bool(cmp0(-12, 0)), bool(cmp0(3.14, 0))
#  > (False, True, True)

%timeit test(cmp0)
12.8 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

但是,如果您希望尽可能清楚(python编程的核心内容),我会使用a != 0 or b != 0。你知道吗

相关问题 更多 >

    热门问题