亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Python 中計時短路會產生意想不到的結果

在 Python 中計時短路會產生意想不到的結果

呼喚遠方 2023-03-01 16:18:17
import time as dt success = Truecan_test = True time = 0for i in range(10000000):  start = dt.time()  if success and can_test:    stop = dt.time()    time+= stop-startprint(f'"and" operation took: {time} seconds')time = 0for i in range(10000000):  start = dt.time()  if success or can_test:    stop = dt.time()    time += stop-startprint(f'"or" operation took: {time} seconds')當我運行上面的 python 程序時,我希望 and 操作比 or 操作慢(因為我了解到短路會減少執行時間)。然而,結果不僅完全相反,而且還在波動。我能理解波動?。ㄒ驗楹笈_進程)??蔀槭裁唇Y果卻相反!怎么了?這是一個示例結果。"and" operation took: 5.200342893600464 seconds"or" operation took: 5.3243467807769775 seconds
查看完整描述

2 回答

?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

這是一個有趣的問題,所以我決定深入調查您的主要顧慮。


# required modules line_profiler, matplotlib, seaborn abd scipy

import time as dt 

from line_profiler import LineProfiler

import matplotlib.pyplot as plt

import seaborn as sns

from scipy import stats


success = True

can_test = True 

def and_op():

    for x in range(2000):

        s = success and can_test

def or_op():

    for x in range(2000):

        s = success or can_test

or_op_list = []

for x in range(0,1000):

    lp = LineProfiler()

    lp_wrapper = lp(or_op)

    lp_wrapper()

    lstats = lp.get_stats()

    total_time = 0

    for v in lstats.timings.values():

        for op in v:

            total_time += op[-1]

            final = op[-1]

        operator = final/total_time

    or_op_list.append(operator)


and_op_list = []

for x in range(0,1000):

    lp = LineProfiler()

    lp_wrapper = lp(and_op)

    lp_wrapper()

    lstats = lp.get_stats()

    total_time = 0

    for v in lstats.timings.values():

        for op in v:

            total_time += op[-1]

            final = op[-1]

        operator = final/total_time

    and_op_list.append(operator)

sns.kdeplot(and_op_list, label = 'AND')

sns.kdeplot(or_op_list, label = 'OR')

plt.show()

print(stats.ttest_ind(and_op_list,or_op_list, equal_var = False))

http://img1.sycdn.imooc.com//63ff0a7700018e2003700248.jpg

pvalue=1.8293386245013954e-103

實際上,與“和”操作相比,“或”具有統計意義并且不同


查看完整回答
反對 回復 2023-03-01
?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

當我在我的機器上運行您的代碼時,它有時打印出來的速度也True and True比 快True or True。


出現這種現象的原因是您dt.time()的代碼以“微秒”(即 1000 納秒)為尺度測量時間,但是,這個微秒尺度太稀疏,無法測量每次執行 or所花費的時間。在大多數情況下, or所花費的時間小于1 微秒。if success and can_test:if success or can_test:if success and can_test:if success or can_test:


因此,在下面的代碼部分中:


for i in range(10000000):

   start = dt.time()

       if success and can_test:  # a dust particle

       stop = dt.time()

       time += stop - start  # measured by a normal scale ruler

for i in range(10000000):

   start = dt.time()

       if success or can_test:  # a dust particle

       stop = dt.time()

       time += stop - start  # measured by a normal scale ruler

您的代碼所做的就像用普通刻度尺測量每個灰塵顆粒并將測量值相加。由于測量誤差巨大,結果失真。


為了進一步調查,如果我們執行下面的代碼(d記錄所花費的時間及其頻率):


import time as dt

from pprint import pprint


success = True

can_test = True


time = 0

d = {}

for i in range(10000000):

    start = dt.time_ns()

    if success and can_test:  # a dust particle

        stop = dt.time_ns()

        diff_time = stop - start  # measurement by a normal scale ruler

        d[diff_time] = d.get(diff_time, 0) + 1

        time += diff_time

print(f'"and" operation took: {time} ns')

print('"and" operation time distribution:')

pprint(d)

print()


time = 0

d = {}

for i in range(10000000):

    start = dt.time_ns()

    if success or can_test:  # a dust particle

        stop = dt.time_ns()

        diff_time = stop - start  # measurement by a normal scale ruler

        d[diff_time] = d.get(diff_time, 0) + 1

        time += diff_time

print(f'"or" operation took: {time} ns')

print('"or" operation time distribution:')

pprint(d)

它將打印如下:


"and" operation took: 1467442000 ns

"and" operation time distribution:

{0: 8565832,

 1000: 1432066,

 2000: 136,

 3000: 24,

 4000: 12,

 5000: 15,

 6000: 10,

 7000: 12,

 8000: 6,

 9000: 7,

 10000: 6,

 11000: 3,

 12000: 191,

 13000: 722,

 14000: 170,

 15000: 462,

 16000: 23,

 17000: 30,

 18000: 27,

 19000: 10,

 20000: 12,

 21000: 11,

 22000: 61,

 23000: 65,

 24000: 9,

 25000: 2,

 26000: 2,

 27000: 3,

 28000: 1,

 29000: 4,

 30000: 4,

 31000: 2,

 32000: 2,

 33000: 2,

 34000: 3,

 35000: 3,

 36000: 5,

 37000: 4,

 40000: 2,

 41000: 1,

 42000: 2,

 43000: 2,

 44000: 2,

 48000: 2,

 50000: 3,

 51000: 3,

 52000: 1,

 53000: 3,

 54000: 1,

 55000: 4,

 58000: 1,

 59000: 2,

 61000: 1,

 62000: 4,

 63000: 1,

 84000: 1,

 98000: 1,

 1035000: 1,

 1043000: 1,

 1608000: 1,

 1642000: 1}


"or" operation took: 1455555000 ns

"or" operation time distribution:

{0: 8569860,

 1000: 1428228,

 2000: 131,

 3000: 31,

 4000: 22,

 5000: 8,

 6000: 8,

 7000: 6,

 8000: 3,

 9000: 6,

 10000: 3,

 11000: 4,

 12000: 173,

 13000: 623,

 14000: 174,

 15000: 446,

 16000: 28,

 17000: 22,

 18000: 31,

 19000: 9,

 20000: 11,

 21000: 8,

 22000: 42,

 23000: 72,

 24000: 7,

 25000: 3,

 26000: 1,

 27000: 5,

 28000: 2,

 29000: 2,

 31000: 1,

 33000: 1,

 34000: 2,

 35000: 4,

 36000: 1,

 37000: 1,

 38000: 2,

 41000: 1,

 44000: 1,

 45000: 2,

 46000: 2,

 47000: 2,

 48000: 2,

 49000: 1,

 50000: 1,

 51000: 2,

 53000: 1,

 61000: 1,

 64000: 1,

 65000: 1,

 942000: 1}

我們可以看到大約 85.7% 的嘗試測量時間(8565832 / 10000000等于0.8565832和8569860 / 10000000等于0.8569860)都失敗了,因為它只測量了0納秒。大約 14.3% 的嘗試測量時間(1432066 / 10000000等于0.1432066和1428228/10000000等于0.1428228)測量的是1000納秒。1000而且,不用說,嘗試測量時間的其余部分(不到 0.1%)也導致了納秒的銷售。我們可以看到,微秒級太稀疏,無法衡量每次執行所花費的時間。


但是我們仍然可以使用普通的刻度尺。通過收集灰塵顆粒并使用尺子測量灰塵球。所以我們可以試試下面的代碼:


import time as dt


success = True

can_test = True


start = dt.time()

for i in range(10000000):  # getting together the dust particles

    if success and can_test:  # a dust particle

        pass

stop = dt.time()

time = stop - start  # measure the size of the dustball

print(f'"and" operation took: {time} seconds')


start = dt.time()

for i in range(10000000):  # getting together the dust particles

    if success or can_test:  # a dust particle

        pass

stop = dt.time()

time = stop - start  # measure the size of the dustball

print(f'"or" operation took: {time} seconds')

它將打印如下:


"and" operation took: 0.6261420249938965 seconds

"or" operation took: 0.48876094818115234 seconds

或者,我們可以使用一把細尺 dt.perf_counter(),它可以精確測量出每一個灰塵顆粒的大小,如下所示:


import time as dt


success = True

can_test = True


time = 0

for i in range(10000000):

    start = dt.perf_counter()

    if success and can_test:  # a dust particle

        stop = dt.perf_counter()

        time += stop - start  # measured by a fine-scale ruler

print(f'"and" operation took: {time} seconds')


time = 0

for i in range(10000000):

    start = dt.perf_counter()

    if success or can_test:  # a dust particle

        stop = dt.perf_counter()

        time += stop - start  # measured by a fine-scale ruler

print(f'"or" operation took: {time} seconds')

它將打印如下:


"and" operation took: 1.6929048989996773 seconds

"or" operation took: 1.3965214280016083 seconds

當然,True or True比True and True!


查看完整回答
反對 回復 2023-03-01
  • 2 回答
  • 0 關注
  • 130 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號