<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>

          12個(gè)Python循環(huán)中的性能監(jiān)控與優(yōu)化工具和技巧

          共 6116字,需瀏覽 13分鐘

           ·

          2024-07-31 17:00

          Python客棧設(shè)為“星標(biāo)?
          第一時(shí)間收到最新資訊

          在Python編程中,循環(huán)是執(zhí)行重復(fù)任務(wù)的核心結(jié)構(gòu)。然而,不當(dāng)?shù)难h(huán)使用可能會(huì)導(dǎo)致程序運(yùn)行緩慢,甚至崩潰。本篇文章將逐步引導(dǎo)你了解如何監(jiān)控和優(yōu)化Python中的循環(huán)性能,涵蓋12種實(shí)用的工具和技巧。

          1. 使用timeit模塊進(jìn)行基準(zhǔn)測(cè)試

          timeit是Python自帶的一個(gè)模塊,用于測(cè)量小段代碼的執(zhí)行時(shí)間,非常適合用來(lái)對(duì)比不同循環(huán)實(shí)現(xiàn)的效率。

          import timeit

          # 循環(huán)遍歷列表
          def loop_list():
              lst = [i for i in range(1000)]
              for i in lst:
                  pass

          # 使用列表推導(dǎo)式
          def list_comprehension():
              [i for i in range(1000)]

          print("Loop List:", timeit.timeit(loop_list, number=1000))
          print("List Comprehension:", timeit.timeit(list_comprehension, number=1000))

          2. 列表推導(dǎo)式代替循環(huán)

          列表推導(dǎo)式通常比循環(huán)構(gòu)建列表更快。

          # 使用循環(huán)創(chuàng)建列表
          lst1 = []
          for i in range(10):
              lst1.append(i)

          # 使用列表推導(dǎo)式創(chuàng)建列表
          lst2 = [i for i in range(10)]

          # 輸出兩個(gè)列表是否相等
          print(lst1 == lst2)

          3. 使用enumerate()避免索引訪問(wèn)

          當(dāng)需要同時(shí)訪問(wèn)元素及其索引時(shí),使用enumerate()可以提高效率。

          names = ['Alice''Bob''Charlie']
          for index, name in enumerate(names):
              print(f"Index {index}{name}")

          4. 使用生成器表達(dá)式節(jié)省內(nèi)存

          生成器表達(dá)式在迭代時(shí)才產(chǎn)生值,不會(huì)一次性加載所有數(shù)據(jù)到內(nèi)存。

          # 列表推導(dǎo)式
          numbers_list = [x for x in range(1000000)]

          # 生成器表達(dá)式
          numbers_gen = (x for x in range(1000000))

          # 測(cè)試內(nèi)存使用
          import sys
          print("List Memory Usage:", sys.getsizeof(numbers_list))
          print("Generator Memory Usage:", sys.getsizeof(numbers_gen))

          5. 避免在循環(huán)內(nèi)進(jìn)行計(jì)算

          如果某個(gè)計(jì)算結(jié)果在循環(huán)內(nèi)不變,應(yīng)將其移到循環(huán)外。

          length = len(lst)
          for i in range(length):
              # 使用length變量而不是len(lst),避免多次調(diào)用len()
              pass

          6. 使用itertools模塊

          itertools提供了多種高效處理迭代器的函數(shù)。

          from itertools import cycle

          colors = ['red''green''blue']
          for color in cycle(colors):
              if input() == 'q':
                  break
              print(color)

          7. 使用setdict檢查成員

          setdict的成員檢查比列表快得多。

          my_set = set([123])
          if 2 in my_set:
              print("Found!")

          8. 盡量減少全局變量的訪問(wèn)

          在循環(huán)內(nèi)部頻繁訪問(wèn)全局變量會(huì)降低性能。

          counter = 0
          for _ in range(1000000):
              counter += 1  # 減少全局變量訪問(wèn),考慮使用局部變量

          9. 使用map()filter()

          這些內(nèi)置函數(shù)可以并行處理數(shù)據(jù),特別是在多核處理器上。

          numbers = [12345]
          squares = list(map(lambda x: x**2, numbers))
          evens = list(filter(lambda x: x % 2 == 0, numbers))

          10. 使用concurrent.futures并行處理

          對(duì)于CPU密集型任務(wù),使用并行處理可以顯著提高速度。

          from concurrent.futures import ThreadPoolExecutor

          def square(x):
              return x ** 2

          with ThreadPoolExecutor() as executor:
              results = list(executor.map(square, [1234]))

          11. 使用cProfile進(jìn)行性能分析

          cProfile是一個(gè)強(qiáng)大的分析工具,可以顯示函數(shù)的調(diào)用次數(shù)和執(zhí)行時(shí)間。

          import cProfile

          def my_function():
              # 你的代碼

          cProfile.run('my_function()')

          12. 編譯成C語(yǔ)言

          使用cythonnumba將Python代碼編譯成C語(yǔ)言,可以極大提升性能。

          # 使用Numba裝飾器加速函數(shù)
          from numba import njit

          @njit
          def add(a, b):
              return a + b

          print(add(12))

          實(shí)戰(zhàn)案例分析:大規(guī)模數(shù)據(jù)處理的循環(huán)優(yōu)化

          假設(shè)你正在處理一個(gè)包含百萬(wàn)級(jí)別的數(shù)據(jù)集,需要對(duì)其進(jìn)行清洗和轉(zhuǎn)換。原始的循環(huán)處理方式可能非常慢,我們可以結(jié)合前面提到的技巧來(lái)優(yōu)化這個(gè)過(guò)程。

          原始代碼:

          data = [i for i in range(1000000)]

          def process_data(data):
              processed_data = []
              for item in data:
                  if item % 2 == 0:  # 假設(shè)只處理偶數(shù)
                      processed_data.append(item * 2)  # 對(duì)偶數(shù)進(jìn)行處理
              return processed_data

          result = process_data(data)

          優(yōu)化方案:

          1. 使用列表推導(dǎo)式替代循環(huán):

          result = [item * 2 for item in data if item % 2 == 0]

          2. 使用numba庫(kù)進(jìn)行JIT編譯:

          from numba import njit

          @njit
          def process_data_optimized(data):
              processed_data = []
              for item in data:
                  if item % 2 == 0:
                      processed_data.append(item * 2)
              return processed_data

          result = process_data_optimized(data)

          3. 使用pandas庫(kù)處理數(shù)據(jù):

          import pandas as pd

          df = pd.DataFrame(data, columns=['value'])
          result = df[df['value'] % 2 == 0]['value'] * 2

          4. 利用多線程或進(jìn)程并行處理:

          from concurrent.futures import ProcessPoolExecutor

          def process_chunk(chunk):
              return [item * 2 for item in chunk if item % 2 == 0]

          with ProcessPoolExecutor() as executor:
              chunks = [data[i:i+10000for i in range(0, len(data), 10000)]
              results = list(executor.map(process_chunk, chunks))
              result = sum(results, [])

          往期回顧

          1、Linux Mint 22“Wilma”正式發(fā)布
          2、不到2MB,很炸裂的神器!
          3、Win11新功能:可直接查看和管理安卓手機(jī)中的文件了
          4、程序員應(yīng)該掌握的三種編程語(yǔ)言——有Zig無(wú)Rust?
          5、學(xué)了十幾種編程語(yǔ)言后,我終于悟了!
                


          點(diǎn)擊關(guān)注公眾號(hào),閱讀更多精彩內(nèi)容

          瀏覽 98
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  大鸡吧网站 | 先锋成人视频 | japαnese老熟女老熟妇 | 亚洲综合13p | 欧美日韩中文字幕在线视频 |