簡體   English   中英

將“with”語句分解為各種函數

[英]decompose "with" statements to various functions

我編寫了一個通用框架來幫助我對代碼關鍵部分進行基准測試。

這是對框架的解釋,最后是我面臨的問題以及我對解決方案的想法很少。

基本上,我正在尋找更優雅的解決方案

假設我有一個執行此操作的函數(以偽代碼形式):

#Pseudo Code - Don't expect it to run

def foo():
   do_begin()
   do_critical()
   some_value = do_end()
   return some_value

我想在循環中多次運行“do_critical”部分並測量時間但仍然獲得返回值。

所以,我寫了 BenchMarker 類,它的 api 是這樣的:

#Pseudo Code - Don't expect it to run

bm = BenchMarker(first=do_begin, critical=do_critical, end=do_end)
bm.start_benchmarking()
returned_value = bm.returned_value
benchmark_result = bm.time

該 Benckmarker 內部執行以下操作:

#Pseudo Code - Don't expect it to run

class BenchMarker:    
  def __init__(self):
     .....

  def start_benchmarking(self):
    first()
    t0 = take_time
    for i in range(n_loops):
      critical()
    t1 = take_time
    self.time = (t1-t0)/n_loops

    value = end()
    self.returned_value = value

重要的是,我還能夠在 first、critical 和 end 函數之間傳遞上下文,但為了簡單起見,我省略了它,因為這不是我的問題的要點。

在以下用例之前,這個框架就像一個魅力:

我有以下代碼

#Pseudo Code - Don't expect it to run    

def bar():
  do_begin()

  with some_context_manager() as ctx:
    do_critical()

  some_value = do_end()
  return some_value

現在,經過這么長的介紹(對不起......),我開始討論真正的問題。

我不想在時間測量循環中運行“with 語句”,但關鍵代碼需要上下文管理器。

所以我基本上想要的相當於bar的以下分解:

first ->  do_begin() + "what happens in the with before the with body"
critical -> do_critical()
end -> "what happens after the with body" + do_end()

我想到的兩個解決方案(但我不喜歡):

解決方案 1模仿 with 在引擎蓋下的作用

  • 在 first()m 的末尾創建上下文管理器對象 + 運行它的enter () 函數
  • 在end()開始時,調用上下文管理器exit ()函數

解決方案 2框架增強以處理 CM

向框架添加一個“上下文工作模式”(標志,隨便……),“start_benchmarking”流程將如下所示:

#Pseudo Code - Don't expect it to run 

def start_benchmarking(self):
  first() #including instantiating the context manager
  ctx = get_the_context_manager_created_in_first()      

  with ctx ...:

    t0 = take_time
    for i in range(n_loops):
      critical()
    t1 = take_time

  self.time = (t1-t0)/n_loops      
  value = end()
  self.returned_value = value

還有其他更優雅的解決方案嗎?

這太復雜了。 我無法弄清楚為什么你真的想要這樣做,但假設你有理由,只需創建一個函數來為你計時:

def run_func_n_times(n_times, func, *args, **kwargs):
    start = time.time()
    for _ in range(n_times):
        res = func(*args, **kwargs)
    return res, (time.time() - start) / n_times

不需要一個類,只需要一個簡單的函數:

def example():
    do_begin()
    print('look, i am here')
    with ctx() as blah:
        res, timed = run_func_n_times(27, f, foo, bar)
    do_end()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM