<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python 實現(xiàn)循環(huán)的最快方式(for、while 等速度對比)

          共 2931字,需瀏覽 6分鐘

           ·

          2021-12-11 05:33

          作者:StarryLand
          來源:https://www.starky.ltd/2021/11/23/the-fastest-way-to-loop-in-python

          眾所周知,Python 不是一種執(zhí)行效率較高的語言。此外在任何語言中,循環(huán)都是一種非常消耗時間的操作。假如任意一種簡單的單步操作耗費的時間為 1 個單位,將此操作重復(fù)執(zhí)行上萬次,最終耗費的時間也將增長上萬倍。

          whilefor 是 Python 中常用的兩種實現(xiàn)循環(huán)的關(guān)鍵字,它們的運行效率實際上是有差距的。比如下面的測試代碼:

          import?timeit


          def?while_loop(n=100_000_000):
          ????i?=?0
          ????s?=?0
          ????while?i?????????s?+=?i
          ????????i?+=?1
          ????return?s


          def?for_loop(n=100_000_000):
          ????s?=?0
          ????for?i?in?range(n):
          ????????s?+=?i
          ????return?s


          def?main():
          ????print('while?loop\t\t',?timeit.timeit(while_loop,?number=1))
          ????print('for?loop\t\t',?timeit.timeit(for_loop,?number=1))


          if?__name__?==?'__main__':
          ????main()
          #?=>?while?loop???????????????4.718853999860585
          #?=>?for?loop?????????????????3.211570399813354

          這是一個簡單的求和操作,計算從 1 到 n 之間所有自然數(shù)的總和??梢钥吹?for 循環(huán)相比 while 要快 1.5 秒。

          其中的差距主要在于兩者的機制不同。

          在每次循環(huán)中,while 實際上比 for 多執(zhí)行了兩步操作:邊界檢查和變量 i 的自增。即每進行一次循環(huán),while 都會做一次邊界檢查 (while i < n)和自增計算(i +=1)。這兩步操作都是顯式的純 Python 代碼。

          for 循環(huán)不需要執(zhí)行邊界檢查和自增操作,沒有增加顯式的 Python 代碼(純 Python 代碼效率低于底層的 C 代碼)。當循環(huán)的次數(shù)足夠多,就出現(xiàn)了明顯的效率差距。

          可以再增加兩個函數(shù),在 for 循環(huán)中加上不必要的邊界檢查和自增計算:

          import?timeit


          def?while_loop(n=100_000_000):
          ????i?=?0
          ????s?=?0
          ????while?i?????????s?+=?i
          ????????i?+=?1
          ????return?s


          def?for_loop(n=100_000_000):
          ????s?=?0
          ????for?i?in?range(n):
          ????????s?+=?i
          ????return?s


          def?for_loop_with_inc(n=100_000_000):
          ????s?=?0
          ????for?i?in?range(n):
          ????????s?+=?i
          ????????i?+=?1
          ????return?s


          def?for_loop_with_test(n=100_000_000):
          ????s?=?0
          ????for?i?in?range(n):
          ????????if?i?????????????pass
          ????????s?+=?i
          ????return?s


          def?main():
          ????print('while?loop\t\t',?timeit.timeit(while_loop,?number=1))
          ????print('for?loop\t\t',?timeit.timeit(for_loop,?number=1))
          ????print('for?loop?with?increment\t\t',
          ??????????timeit.timeit(for_loop_with_inc,?number=1))
          ????print('for?loop?with?test\t\t',?timeit.timeit(for_loop_with_test,?number=1))


          if?__name__?==?'__main__':
          ????main()
          #?=>?while?loop???????????????4.718853999860585
          #?=>?for?loop?????????????????3.211570399813354
          #?=>?for?loop?with?increment??????????4.602369500091299
          #?=>?for?loop?with?test???????????????4.18337869993411

          可以看出,增加的邊界檢查和自增操作確實大大影響了 for 循環(huán)的執(zhí)行效率。

          前面提到過,Python 底層的解釋器和內(nèi)置函數(shù)是用 C 語言實現(xiàn)的。而 C 語言的執(zhí)行效率遠大于 Python。

          對于上面的求等差數(shù)列之和的操作,借助于 Python 內(nèi)置的 sum 函數(shù),可以獲得遠大于 forwhile 循環(huán)的執(zhí)行效率。

          import?timeit


          def?while_loop(n=100_000_000):
          ????i?=?0
          ????s?=?0
          ????while?i?????????s?+=?i
          ????????i?+=?1
          ????return?s


          def?for_loop(n=100_000_000):
          ????s?=?0
          ????for?i?in?range(n):
          ????????s?+=?i
          ????return?s


          def?sum_range(n=100_000_000):
          ????return?sum(range(n))


          def?main():
          ????print('while?loop\t\t',?timeit.timeit(while_loop,?number=1))
          ????print('for?loop\t\t',?timeit.timeit(for_loop,?number=1))
          ????print('sum?range\t\t',?timeit.timeit(sum_range,?number=1))


          if?__name__?==?'__main__':
          ????main()
          #?=>?while?loop???????????????4.718853999860585
          #?=>?for?loop?????????????????3.211570399813354
          #?=>?sum?range????????????????0.8658821999561042

          可以看到,使用內(nèi)置函數(shù) sum 替代循環(huán)之后,代碼的執(zhí)行效率實現(xiàn)了成倍的增長。

          內(nèi)置函數(shù) sum 的累加操作實際上也是一種循環(huán),但它由 C 語言實現(xiàn),而 for 循環(huán)中的求和操作是由純 Python 代碼 s += i 實現(xiàn)的。C > Python。

          再拓展一下思維。小時候都聽說過童年高斯巧妙地計算 1 到 100 之和的故事。1…100 之和等于 (1 + 100) * 50。這個計算方法同樣可以應(yīng)用到上面的求和操作中。

          import?timeit


          def?while_loop(n=100_000_000):
          ????i?=?0
          ????s?=?0
          ????while?i?????????s?+=?i
          ????????i?+=?1
          ????return?s


          def?for_loop(n=100_000_000):
          ????s?=?0
          ????for?i?in?range(n):
          ????????s?+=?i
          ????return?s


          def?sum_range(n=100_000_000):
          ????return?sum(range(n))


          def?math_sum(n=100_000_000):
          ????return?(n?*?(n?-?1))?//?2


          def?main():
          ????print('while?loop\t\t',?timeit.timeit(while_loop,?number=1))
          ????print('for?loop\t\t',?timeit.timeit(for_loop,?number=1))
          ????print('sum?range\t\t',?timeit.timeit(sum_range,?number=1))
          ????print('math?sum\t\t',?timeit.timeit(math_sum,?number=1))


          if?__name__?==?'__main__':
          ????main()
          #?=>?while?loop???????????????4.718853999860585
          #?=>?for?loop?????????????????3.211570399813354
          #?=>?sum?range????????????????0.8658821999561042
          #?=>?math?sum?????????????????2.400018274784088e-06

          最終 math sum 的執(zhí)行時間約為 2.4e-6,縮短了上百萬倍。這里的思路就是,既然循環(huán)的效率低,一段代碼要重復(fù)執(zhí)行上億次。

          索性直接不要循環(huán),通過數(shù)學(xué)公式,把上億次的循環(huán)操作變成只有一步操作。效率自然得到了空前的加強。

          最后的結(jié)論(有點謎語人):

          實現(xiàn)循環(huán)的最快方式—— —— ——就是不用循環(huán)

          對于 Python 而言,則盡可能地使用內(nèi)置函數(shù),將循環(huán)中的純 Python 代碼降到最低。

          參考資料

          The Fastest Way to Loop in Python - mCoding? (https://youtu.be/Qgevy75co8c)




          推薦閱讀:

          入門:?最全的零基礎(chǔ)學(xué)Python的問題? |?零基礎(chǔ)學(xué)了8個月的Python??|?實戰(zhàn)項目?|學(xué)Python就是這條捷徑


          干貨:爬取豆瓣短評,電影《后來的我們》?|?38年NBA最佳球員分析?|? ?從萬眾期待到口碑撲街!唐探3令人失望? |?笑看新倚天屠龍記?|?燈謎答題王?|用Python做個海量小姐姐素描圖?|碟中諜這么火,我用機器學(xué)習(xí)做個迷你推薦系統(tǒng)電影


          趣味:彈球游戲? |?九宮格? |?漂亮的花?|?兩百行Python《天天酷跑》游戲!


          AI:?會做詩的機器人?|?給圖片上色?|?預(yù)測收入?|?碟中諜這么火,我用機器學(xué)習(xí)做個迷你推薦系統(tǒng)電影


          小工具:?Pdf轉(zhuǎn)Word,輕松搞定表格和水印!?|?一鍵把html網(wǎng)頁保存為pdf!|??再見PDF提取收費!?|?用90行代碼打造最強PDF轉(zhuǎn)換器,word、PPT、excel、markdown、html一鍵轉(zhuǎn)換?|?制作一款釘釘?shù)蛢r機票提示器!?|60行代碼做了一個語音壁紙切換器天天看小姐姐!


          年度爆款文案


          點閱讀原文,看200個Python案例

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  香蕉久操 | 亚洲蜜桃精品 | 99久久久国产精品无码 | 亚洲无码短视频 | 无码精品人妻一区二区三蜜桃 |