日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

加速Python循環(huán)的12種方法,最高可以提速900倍

來(lái)源: 責(zé)編: 時(shí)間:2024-01-03 17:22:12 261觀看
導(dǎo)讀在本文中,我將介紹一些簡(jiǎn)單的方法,可以將Python for循環(huán)的速度提高1.3到900倍。Python內(nèi)建的一個(gè)常用功能是timeit模塊。下面幾節(jié)中我們將使用它來(lái)度量循環(huán)的當(dāng)前性能和改進(jìn)后的性能。對(duì)于每種方法,我們通過(guò)運(yùn)行測(cè)試來(lái)建

在本文中,我將介紹一些簡(jiǎn)單的方法,可以將Python for循環(huán)的速度提高1.3到900倍。OjJ28資訊網(wǎng)——每日最新資訊28at.com

Python內(nèi)建的一個(gè)常用功能是timeit模塊。下面幾節(jié)中我們將使用它來(lái)度量循環(huán)的當(dāng)前性能和改進(jìn)后的性能。OjJ28資訊網(wǎng)——每日最新資訊28at.com

對(duì)于每種方法,我們通過(guò)運(yùn)行測(cè)試來(lái)建立基線,該測(cè)試包括在10次測(cè)試運(yùn)行中運(yùn)行被測(cè)函數(shù)100K次(循環(huán)),然后計(jì)算每個(gè)循環(huán)的平均時(shí)間(以納秒為單位,ns)。OjJ28資訊網(wǎng)——每日最新資訊28at.com

OjJ28資訊網(wǎng)——每日最新資訊28at.com

幾個(gè)簡(jiǎn)單方法

1、列表推導(dǎo)式

# Baseline version (Inefficient way) # Calculating the power of numbers # Without using List Comprehension def test_01_v0(numbers):   output = []   for n in numbers:       output.append(n ** 2.5)   return output  # Improved version # (Using List Comprehension) def test_01_v1(numbers):   output = [n ** 2.5 for n in numbers]   return output

結(jié)果如下:OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 32.158 ns per loop      Improved: 16.040 ns per loop % Improvement: 50.1 %      Speedup: 2.00x

可以看到使用列表推導(dǎo)式可以得到2倍速的提高OjJ28資訊網(wǎng)——每日最新資訊28at.com

2、在外部計(jì)算長(zhǎng)度

如果需要依靠列表的長(zhǎng)度進(jìn)行迭代,請(qǐng)?jiān)趂or循環(huán)之外進(jìn)行計(jì)算。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Baseline version (Inefficient way) # (Length calculation inside for loop) def test_02_v0(numbers):   output_list = []   for i in range(len(numbers)):     output_list.append(i * 2)   return output_list  # Improved version # (Length calculation outside for loop) def test_02_v1(numbers):   my_list_length = len(numbers)   output_list = []   for i in range(my_list_length):     output_list.append(i * 2)   return output_list

通過(guò)將列表長(zhǎng)度計(jì)算移出for循環(huán),加速1.6倍,這個(gè)方法可能很少有人知道吧。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 112.135 ns per loop      Improved: 68.304 ns per loop % Improvement: 39.1 %      Speedup: 1.64x

3、使用Set

在使用for循環(huán)進(jìn)行比較的情況下使用set。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Use for loops for nested lookups def test_03_v0(list_1, list_2):   # Baseline version (Inefficient way)   # (nested lookups using for loop)   common_items = []   for item in list_1:       if item in list_2:           common_items.append(item)   return common_items  def test_03_v1(list_1, list_2):   # Improved version   # (sets to replace nested lookups)   s_1 = set(list_1)   s_2 = set(list_2)   output_list = []   common_items = s_1.intersection(s_2)   return common_items

在使用嵌套for循環(huán)進(jìn)行比較的情況下,使用set加速498xOjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 9047.078 ns per loop      Improved:   18.161 ns per loop % Improvement: 99.8 %      Speedup: 498.17x

4、跳過(guò)不相關(guān)的迭代

避免冗余計(jì)算,即跳過(guò)不相關(guān)的迭代。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Example of inefficient code used to find  # the first even square in a list of numbers def function_do_something(numbers):   for n in numbers:     square = n * n     if square % 2 == 0:         return square    return None  # No even square found  # Example of improved code that  # finds result without redundant computations def function_do_something_v1(numbers):   even_numbers = [i for n in numbers if n%2==0]   for n in even_numbers:     square = n * n     return square    return None  # No even square found

這個(gè)方法要在設(shè)計(jì)for循環(huán)內(nèi)容的時(shí)候進(jìn)行代碼設(shè)計(jì),具體能提升多少可能根據(jù)實(shí)際情況不同:OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 16.912 ns per loop      Improved: 8.697 ns per loop % Improvement: 48.6 %      Speedup: 1.94x

5、代碼合并

在某些情況下,直接將簡(jiǎn)單函數(shù)的代碼合并到循環(huán)中可以提高代碼的緊湊性和執(zhí)行速度。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Example of inefficient code # Loop that calls the is_prime function n times. def is_prime(n):   if n <= 1:     return False   for i in range(2, int(n**0.5) + 1):     if n % i == 0:       return False    return True  def test_05_v0(n):   # Baseline version (Inefficient way)   # (calls the is_prime function n times)   count = 0   for i in range(2, n + 1):     if is_prime(i):       count += 1   return count  def test_05_v1(n):   # Improved version   # (inlines the logic of the is_prime function)   count = 0   for i in range(2, n + 1):     if i <= 1:       continue     for j in range(2, int(i**0.5) + 1):       if i % j == 0:         break     else:       count += 1   return count

這樣也可以提高1.3倍OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 1271.188 ns per loop      Improved: 939.603 ns per loop % Improvement: 26.1 %      Speedup: 1.35x

這是為什么呢?OjJ28資訊網(wǎng)——每日最新資訊28at.com

調(diào)用函數(shù)涉及開(kāi)銷,例如在堆棧上推入和彈出變量、函數(shù)查找和參數(shù)傳遞。當(dāng)一個(gè)簡(jiǎn)單的函數(shù)在循環(huán)中被重復(fù)調(diào)用時(shí),函數(shù)調(diào)用的開(kāi)銷會(huì)增加并影響性能。所以將函數(shù)的代碼直接內(nèi)聯(lián)到循環(huán)中可以消除這種開(kāi)銷,從而可能顯著提高速度。OjJ28資訊網(wǎng)——每日最新資訊28at.com

??但是這里需要注意,平衡代碼可讀性和函數(shù)調(diào)用的頻率是一個(gè)要考慮的問(wèn)題。OjJ28資訊網(wǎng)——每日最新資訊28at.com

一些小技巧

6.避免重復(fù)

考慮避免重復(fù)計(jì)算,其中一些計(jì)算可能是多余的,并且會(huì)減慢代碼的速度。相反,在適用的情況下考慮預(yù)計(jì)算。OjJ28資訊網(wǎng)——每日最新資訊28at.com

def test_07_v0(n):   # Example of inefficient code   # Repetitive calculation within nested loop   result = 0   for i in range(n):     for j in range(n):       result += i * j   return result  def test_07_v1(n):   # Example of improved code   # Utilize precomputed values to help speedup   pv = [[i * j for j in range(n)] for i in range(n)]   result = 0   for i in range(n):     result += sum(pv[i][:i+1])   return result

結(jié)果如下OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 139.146 ns per loop      Improved: 92.325 ns per loop % Improvement: 33.6 %      Speedup: 1.51x

7、使用Generators

生成器支持延遲求值,也就是說(shuō),只有當(dāng)你向它請(qǐng)求下一個(gè)值時(shí),里面的表達(dá)式才會(huì)被求值,動(dòng)態(tài)處理數(shù)據(jù)有助于減少內(nèi)存使用并提高性能。尤其是大型數(shù)據(jù)集中OjJ28資訊網(wǎng)——每日最新資訊28at.com

def test_08_v0(n):   # Baseline version (Inefficient way)   # (Inefficiently calculates the nth Fibonacci   # number using a list)   if n <= 1:     return n   f_list = [0, 1]   for i in range(2, n + 1):     f_list.append(f_list[i - 1] + f_list[i - 2])   return f_list[n]  def test_08_v1(n):   # Improved version   # (Efficiently calculates the nth Fibonacci   # number using a generator)   a, b = 0, 1   for _ in range(n):     yield a     a, b = b, a + b

可以看到提升很明顯:OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 0.083 ns per loop      Improved: 0.004 ns per loop % Improvement: 95.5 %      Speedup: 22.06x

8、map()函數(shù)

使用Python內(nèi)置的map()函數(shù)。它允許在不使用顯式for循環(huán)的情況下處理和轉(zhuǎn)換可迭代對(duì)象中的所有項(xiàng)。OjJ28資訊網(wǎng)——每日最新資訊28at.com

def some_function_X(x):   # This would normally be a function containing application logic   # which required it to be made into a separate function   # (for the purpose of this test, just calculate and return the square)   return x**2  def test_09_v0(numbers):   # Baseline version (Inefficient way)   output = []   for i in numbers:     output.append(some_function_X(i))    return output  def test_09_v1(numbers):   # Improved version   # (Using Python's built-in map() function)   output = map(some_function_X, numbers)   return output

使用Python內(nèi)置的map()函數(shù)代替顯式的for循環(huán)加速了970x。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 4.402 ns per loop      Improved: 0.005 ns per loop % Improvement: 99.9 %      Speedup: 970.69x

這是為什么呢?OjJ28資訊網(wǎng)——每日最新資訊28at.com

map()函數(shù)是用C語(yǔ)言編寫的,并且經(jīng)過(guò)了高度優(yōu)化,因此它的內(nèi)部隱含循環(huán)比常規(guī)的Python for循環(huán)要高效得多。因此速度加快了,或者可以說(shuō)Python還是太慢,哈。OjJ28資訊網(wǎng)——每日最新資訊28at.com

9、使用Memoization

記憶優(yōu)化算法的思想是緩存(或“記憶”)昂貴的函數(shù)調(diào)用的結(jié)果,并在出現(xiàn)相同的輸入時(shí)返回它們。它可以減少冗余計(jì)算,加快程序速度。OjJ28資訊網(wǎng)——每日最新資訊28at.com

首先是低效的版本。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Example of inefficient code def fibonacci(n):   if n == 0:     return 0   elif n == 1:     return 1   return fibonacci(n - 1) + fibonacci(n-2)  def test_10_v0(list_of_numbers):   output = []   for i in numbers:     output.append(fibonacci(i))    return output

然后我們使用Python的內(nèi)置functools的lru_cache函數(shù)。OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Example of efficient code # Using Python's functools' lru_cache function import functools  @functools.lru_cache() def fibonacci_v2(n):   if n == 0:     return 0   elif n == 1:     return 1   return fibonacci_v2(n - 1) + fibonacci_v2(n-2)  def _test_10_v1(numbers):   output = []   for i in numbers:     output.append(fibonacci_v2(i))    return output

結(jié)果如下:OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 63.664 ns per loop      Improved: 1.104 ns per loop % Improvement: 98.3 %      Speedup: 57.69x

使用Python的內(nèi)置functools的lru_cache函數(shù)使用Memoization加速57x。OjJ28資訊網(wǎng)——每日最新資訊28at.com

lru_cache函數(shù)是如何實(shí)現(xiàn)的?OjJ28資訊網(wǎng)——每日最新資訊28at.com

“LRU”是“Least Recently Used”的縮寫。lru_cache是一個(gè)裝飾器,可以應(yīng)用于函數(shù)以啟用memoization。它將最近函數(shù)調(diào)用的結(jié)果存儲(chǔ)在緩存中,當(dāng)再次出現(xiàn)相同的輸入時(shí),可以提供緩存的結(jié)果,從而節(jié)省了計(jì)算時(shí)間。lru_cache函數(shù),當(dāng)作為裝飾器應(yīng)用時(shí),允許一個(gè)可選的maxsize參數(shù),maxsize參數(shù)決定了緩存的最大大小(即,它為多少個(gè)不同的輸入值存儲(chǔ)結(jié)果)。如果maxsize參數(shù)設(shè)置為None,則禁用LRU特性,緩存可以不受約束地增長(zhǎng),這會(huì)消耗很多的內(nèi)存。這是最簡(jiǎn)單的空間換時(shí)間的優(yōu)化方法。OjJ28資訊網(wǎng)——每日最新資訊28at.com

10、向量化

import numpy as np  def test_11_v0(n):   # Baseline version   # (Inefficient way of summing numbers in a range)   output = 0   for i in range(0, n):     output = output + i    return output  def test_11_v1(n):   # Improved version   # (# Efficient way of summing numbers in a range)   output = np.sum(np.arange(n))   return output

向量化一般用于機(jī)器學(xué)習(xí)的數(shù)據(jù)處理庫(kù)numpy和pandasOjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 32.936 ns per loop      Improved: 1.171 ns per loop % Improvement: 96.4 %      Speedup: 28.13x

11、避免創(chuàng)建中間列表

使用filterfalse可以避免創(chuàng)建中間列表。它有助于使用更少的內(nèi)存。OjJ28資訊網(wǎng)——每日最新資訊28at.com

def test_12_v0(numbers):   # Baseline version (Inefficient way)   filtered_data = []   for i in numbers:     filtered_data.extend(list(         filter(lambda x: x % 5 == 0,                 range(1, i**2))))      return filtered_data

使用Python的內(nèi)置itertools的filterfalse函數(shù)實(shí)現(xiàn)相同功能的改進(jìn)版本。OjJ28資訊網(wǎng)——每日最新資訊28at.com

from itertools import filterfalse  def test_12_v1(numbers):   # Improved version   # (using filterfalse)   filtered_data = []   for i in numbers:     filtered_data.extend(list(         filterfalse(lambda x: x % 5 != 0,                     range(1, i**2))))          return filtered_data

這個(gè)方法根據(jù)用例的不同,執(zhí)行速度可能沒(méi)有顯著提高,但通過(guò)避免創(chuàng)建中間列表可以降低內(nèi)存使用。我們這里獲得了131倍的提高OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 333167.790 ns per loop      Improved: 2541.850 ns per loop % Improvement: 99.2 %      Speedup: 131.07x

12、高效連接字符串

任何使用+操作符的字符串連接操作都會(huì)很慢,并且會(huì)消耗更多內(nèi)存。使用join代替。OjJ28資訊網(wǎng)——每日最新資訊28at.com

def test_13_v0(l_strings):   # Baseline version (Inefficient way)   # (concatenation using the += operator)   output = ""   for a_str in l_strings:     output += a_str    return output  def test_13_v1(numbers):   # Improved version   # (using join)   output_list = []   for a_str in l_strings:     output_list.append(a_str)    return "".join(output_list)

該測(cè)試需要一種簡(jiǎn)單的方法來(lái)生成一個(gè)較大的字符串列表,所以寫了一個(gè)簡(jiǎn)單的輔助函數(shù)來(lái)生成運(yùn)行測(cè)試所需的字符串列表。OjJ28資訊網(wǎng)——每日最新資訊28at.com

from faker import Faker  def generate_fake_names(count : int=10000):   # Helper function used to generate a    # large-ish list of names   fake = Faker()   output_list = []   for _ in range(count):     output_list.append(fake.name())    return output_list  l_strings = generate_fake_names(count=50000)

結(jié)果如下:OjJ28資訊網(wǎng)——每日最新資訊28at.com

# Summary Of Test Results      Baseline: 32.423 ns per loop      Improved: 21.051 ns per loop % Improvement: 35.1 %      Speedup: 1.54x

使用連接函數(shù)而不是使用+運(yùn)算符加速1.5倍。為什么連接函數(shù)更快?OjJ28資訊網(wǎng)——每日最新資訊28at.com

使用+操作符的字符串連接操作的時(shí)間復(fù)雜度為O(n2),而使用join函數(shù)的字符串連接操作的時(shí)間復(fù)雜度為O(n)。OjJ28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

本文介紹了一些簡(jiǎn)單的方法,將Python for循環(huán)的提升了1.3到970x。OjJ28資訊網(wǎng)——每日最新資訊28at.com

  • 使用Python內(nèi)置的map()函數(shù)代替顯式的for循環(huán)加速970x
  • 使用set代替嵌套的for循環(huán)加速498x[技巧#3]
  • 使用itertools的filterfalse函數(shù)加速131x
  • 使用lru_cache函數(shù)使用Memoization加速57x


OjJ28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-57287-0.html加速Python循環(huán)的12種方法,最高可以提速900倍

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 基于Python的圖像預(yù)處理完整指南

下一篇: Pandas入門的12個(gè)技巧

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 6月安卓手機(jī)性價(jià)比榜:Note 12 Turbo斷層式碾壓

    6月份有一個(gè)618,雖然這是京東周年慶的日子,但別的電商也都不約而同的跟進(jìn)了,反正促銷沒(méi)壞處,廠商和用戶都能滿意。618期間一些產(chǎn)品也出現(xiàn)了歷史低價(jià),那么各個(gè)價(jià)位段的產(chǎn)品性價(jià)比
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個(gè)線程之間通過(guò)某種機(jī)制進(jìn)行協(xié)調(diào)和交互,例如,線程等待和通知機(jī)制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實(shí)現(xiàn)手段有以下幾種方式:Object 類下
  • 三言兩語(yǔ)說(shuō)透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是兩種很有用的技術(shù),可以幫助我們寫出更加優(yōu)雅、泛用的函數(shù)。本文將首先介紹柯里化和反柯里化的概念、實(shí)現(xiàn)原理和應(yīng)用
  • 谷歌KDD'23工作:如何提升推薦系統(tǒng)Ranking模型訓(xùn)練穩(wěn)定性

    谷歌在KDD 2023發(fā)表了一篇工作,探索了推薦系統(tǒng)ranking模型的訓(xùn)練穩(wěn)定性問(wèn)題,分析了造成訓(xùn)練穩(wěn)定性存在問(wèn)題的潛在原因,以及現(xiàn)有的一些提升模型穩(wěn)定性方法的不足,并提出了一種新
  • 深度探索 Elasticsearch 8.X:function_score 參數(shù)解讀與實(shí)戰(zhàn)案例分析

    在 Elasticsearch 中,function_score 可以讓我們?cè)诓樵兊耐瑫r(shí)對(duì)搜索結(jié)果進(jìn)行自定義評(píng)分。function_score 提供了一系列的參數(shù)和函數(shù)讓我們可以根據(jù)需求靈活地進(jìn)行設(shè)置。近期
  • 三分鐘白話RocketMQ系列—— 如何發(fā)送消息

    我們知道RocketMQ主要分為消息 生產(chǎn)、存儲(chǔ)(消息堆積)、消費(fèi) 三大塊領(lǐng)域。那接下來(lái),我們白話一下,RocketMQ是如何發(fā)送消息的,揭秘消息生產(chǎn)全過(guò)程。注意,如果白話中不小心提到相關(guān)代
  • 自律,給不了Keep自由!

    來(lái)源 | 互聯(lián)網(wǎng)品牌官作者 | 李大為編排 | 又耳 審核 | 谷曉輝自律能不能給用戶自由暫時(shí)不好說(shuō),但大概率不能給Keep自由。近日,全球最大的在線健身平臺(tái)Keep正式登陸港交所,努力
  • 8月見(jiàn)!小米MIX Fold 3獲得3C認(rèn)證:支持67W快充

    這段時(shí)間以來(lái),包括三星、一加、榮耀等等有不少品牌旗下的最新折疊屏旗艦都得到了不少爆料,而小米新一代折疊屏旗艦——小米MIX Fold 3此前也屢屢被傳
  • 2納米決戰(zhàn)2025

    集微網(wǎng)報(bào)道 從三強(qiáng)爭(zhēng)霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來(lái)。無(wú)論是老牌勁旅臺(tái)積電、三星,還是誓言重回先進(jìn)制程領(lǐng)先地位的英特爾,甚至初成立不久的新
Top 主站蜘蛛池模板: 台东市| 峡江县| 睢宁县| 河北省| 平泉县| 繁峙县| 黔西| 华池县| 云浮市| 商都县| 子长县| 阿尔山市| 安义县| 长沙市| 荔波县| 巴林左旗| 肇源县| 宣恩县| 长顺县| 读书| 阳泉市| 江源县| 青浦区| 上高县| 红安县| 隆子县| 柳江县| 义马市| 南丰县| 庆云县| 长岛县| 克东县| 于田县| 浦北县| 漾濞| 怀远县| 都江堰市| 三门峡市| 隆林| 蕉岭县| 平凉市|