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

當前位置:首頁 > 科技  > 軟件

加速Python循環的12種方法,最高可以提速900倍

來源: 責編: 時間:2024-01-03 17:22:12 238觀看
導讀在本文中,我將介紹一些簡單的方法,可以將Python for循環的速度提高1.3到900倍。Python內建的一個常用功能是timeit模塊。下面幾節中我們將使用它來度量循環的當前性能和改進后的性能。對于每種方法,我們通過運行測試來建

在本文中,我將介紹一些簡單的方法,可以將Python for循環的速度提高1.3到900倍。uMw28資訊網——每日最新資訊28at.com

Python內建的一個常用功能是timeit模塊。下面幾節中我們將使用它來度量循環的當前性能和改進后的性能。uMw28資訊網——每日最新資訊28at.com

對于每種方法,我們通過運行測試來建立基線,該測試包括在10次測試運行中運行被測函數100K次(循環),然后計算每個循環的平均時間(以納秒為單位,ns)。uMw28資訊網——每日最新資訊28at.com

uMw28資訊網——每日最新資訊28at.com

幾個簡單方法

1、列表推導式

# 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

結果如下:uMw28資訊網——每日最新資訊28at.com

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

可以看到使用列表推導式可以得到2倍速的提高uMw28資訊網——每日最新資訊28at.com

2、在外部計算長度

如果需要依靠列表的長度進行迭代,請在for循環之外進行計算。uMw28資訊網——每日最新資訊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

通過將列表長度計算移出for循環,加速1.6倍,這個方法可能很少有人知道吧。uMw28資訊網——每日最新資訊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循環進行比較的情況下使用set。uMw28資訊網——每日最新資訊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循環進行比較的情況下,使用set加速498xuMw28資訊網——每日最新資訊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、跳過不相關的迭代

避免冗余計算,即跳過不相關的迭代。uMw28資訊網——每日最新資訊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

這個方法要在設計for循環內容的時候進行代碼設計,具體能提升多少可能根據實際情況不同:uMw28資訊網——每日最新資訊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、代碼合并

在某些情況下,直接將簡單函數的代碼合并到循環中可以提高代碼的緊湊性和執行速度。uMw28資訊網——每日最新資訊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倍uMw28資訊網——每日最新資訊28at.com

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

這是為什么呢?uMw28資訊網——每日最新資訊28at.com

調用函數涉及開銷,例如在堆棧上推入和彈出變量、函數查找和參數傳遞。當一個簡單的函數在循環中被重復調用時,函數調用的開銷會增加并影響性能。所以將函數的代碼直接內聯到循環中可以消除這種開銷,從而可能顯著提高速度。uMw28資訊網——每日最新資訊28at.com

??但是這里需要注意,平衡代碼可讀性和函數調用的頻率是一個要考慮的問題。uMw28資訊網——每日最新資訊28at.com

一些小技巧

6.避免重復

考慮避免重復計算,其中一些計算可能是多余的,并且會減慢代碼的速度。相反,在適用的情況下考慮預計算。uMw28資訊網——每日最新資訊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

結果如下uMw28資訊網——每日最新資訊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

生成器支持延遲求值,也就是說,只有當你向它請求下一個值時,里面的表達式才會被求值,動態處理數據有助于減少內存使用并提高性能。尤其是大型數據集中uMw28資訊網——每日最新資訊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

可以看到提升很明顯:uMw28資訊網——每日最新資訊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()函數

使用Python內置的map()函數。它允許在不使用顯式for循環的情況下處理和轉換可迭代對象中的所有項。uMw28資訊網——每日最新資訊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內置的map()函數代替顯式的for循環加速了970x。uMw28資訊網——每日最新資訊28at.com

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

這是為什么呢?uMw28資訊網——每日最新資訊28at.com

map()函數是用C語言編寫的,并且經過了高度優化,因此它的內部隱含循環比常規的Python for循環要高效得多。因此速度加快了,或者可以說Python還是太慢,哈。uMw28資訊網——每日最新資訊28at.com

9、使用Memoization

記憶優化算法的思想是緩存(或“記憶”)昂貴的函數調用的結果,并在出現相同的輸入時返回它們。它可以減少冗余計算,加快程序速度。uMw28資訊網——每日最新資訊28at.com

首先是低效的版本。uMw28資訊網——每日最新資訊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的內置functools的lru_cache函數。uMw28資訊網——每日最新資訊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

結果如下:uMw28資訊網——每日最新資訊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的內置functools的lru_cache函數使用Memoization加速57x。uMw28資訊網——每日最新資訊28at.com

lru_cache函數是如何實現的?uMw28資訊網——每日最新資訊28at.com

“LRU”是“Least Recently Used”的縮寫。lru_cache是一個裝飾器,可以應用于函數以啟用memoization。它將最近函數調用的結果存儲在緩存中,當再次出現相同的輸入時,可以提供緩存的結果,從而節省了計算時間。lru_cache函數,當作為裝飾器應用時,允許一個可選的maxsize參數,maxsize參數決定了緩存的最大大小(即,它為多少個不同的輸入值存儲結果)。如果maxsize參數設置為None,則禁用LRU特性,緩存可以不受約束地增長,這會消耗很多的內存。這是最簡單的空間換時間的優化方法。uMw28資訊網——每日最新資訊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

向量化一般用于機器學習的數據處理庫numpy和pandasuMw28資訊網——每日最新資訊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、避免創建中間列表

使用filterfalse可以避免創建中間列表。它有助于使用更少的內存。uMw28資訊網——每日最新資訊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的內置itertools的filterfalse函數實現相同功能的改進版本。uMw28資訊網——每日最新資訊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

這個方法根據用例的不同,執行速度可能沒有顯著提高,但通過避免創建中間列表可以降低內存使用。我們這里獲得了131倍的提高uMw28資訊網——每日最新資訊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、高效連接字符串

任何使用+操作符的字符串連接操作都會很慢,并且會消耗更多內存。使用join代替。uMw28資訊網——每日最新資訊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)

該測試需要一種簡單的方法來生成一個較大的字符串列表,所以寫了一個簡單的輔助函數來生成運行測試所需的字符串列表。uMw28資訊網——每日最新資訊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)

結果如下:uMw28資訊網——每日最新資訊28at.com

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

使用連接函數而不是使用+運算符加速1.5倍。為什么連接函數更快?uMw28資訊網——每日最新資訊28at.com

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

總結

本文介紹了一些簡單的方法,將Python for循環的提升了1.3到970x。uMw28資訊網——每日最新資訊28at.com

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


uMw28資訊網——每日最新資訊28at.com

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

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

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

下一篇: Pandas入門的12個技巧

標簽:
  • 熱門焦點
  • Raft算法:保障分布式系統共識的穩健之道

    1. 什么是Raft算法?Raft 是英文”Reliable、Replicated、Redundant、And Fault-Tolerant”(“可靠、可復制、可冗余、可容錯”)的首字母縮寫。Raft算法是一種用于在分布式系統
  • 摸魚心法第一章——和配置文件說拜拜

    為了能摸魚我們團隊做了容器化,但是帶來的問題是服務配置文件很麻煩,然后大家在群里進行了“親切友好”的溝通圖片圖片圖片圖片對比就對比,簡單對比下獨立配置中心和k8s作為配
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數量是否小于或等于一個數字。例如,一個擁有三個或更多子項的grid。你可能會想,為什么需要這樣做呢?在某些情況下,一個組件或一個布局可能會
  • 三萬字盤點 Spring 九大核心基礎功能

    大家好,我是三友~~今天來跟大家聊一聊Spring的9大核心基礎功能。話不多說,先上目錄:圖片友情提示,本文過長,建議收藏,嘿嘿嘿!一、資源管理資源管理是Spring的一個核心的基礎功能,不
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 猿輔導與新東方的兩種“歸途”

    作者|卓心月 出品|零態LT(ID:LingTai_LT)如何成為一家偉大企業?答案一定是對&ldquo;勢&rdquo;的把握,這其中最關鍵的當屬對企業戰略的制定,且能夠站在未來看現在,即使這其中的
  • 品牌洞察丨服務本地,美團直播成效幾何?

    來源:17PR7月11日,美團App首頁推薦位出現&ldquo;美團直播&rdquo;的固定入口。在直播聚合頁面,外賣&ldquo;神槍手&rdquo;直播間、美團旅行直播間、美團買菜直播間等均已上線,同時
  • 蘋果140W USB-C充電器:采用氮化鎵技術

    據10 月 30 日 9to5 Mac 消息報道,當蘋果推出新的 MacBook Pro 2021 時,該公司還推出了新的 140W USB-C 充電器,附贈在 MacBook Pro 16 英寸機型的盒子里,也支
  • 聯想小新Pad Pro 12.6將要推出,搭載高通驍龍 870 處理器

    聯想小新Pad Pro 12.6將于秋季新品會上推出,官方按照慣例直接在發布會前給出了機型的所有參數。聯想小新 Pad Pro 12.6 將搭載高通驍龍 870 處理器,重量為 5
Top 主站蜘蛛池模板: 辽宁省| 库尔勒市| 邹城市| 巴东县| 广宗县| 惠来县| 大洼县| 类乌齐县| 北海市| 靖州| 乐陵市| 高邑县| 临颍县| 内江市| 喀喇| 灵石县| 内黄县| 江安县| 沽源县| 明光市| 繁昌县| 芜湖县| 洪泽县| 长丰县| 商都县| 锡林郭勒盟| 陆川县| 商河县| 洪泽县| 城步| 昭平县| 怀远县| 武清区| 丰宁| 丰顺县| 婺源县| 红桥区| 南华县| 满洲里市| 新乡市| 元阳县|