2017-01-05 21 views
1

我們有一個使用c庫調用一些低級函數的python腳本。 由於代碼結構的原因,我們希望在每次c調用之前存儲堆棧跟蹤/調用堆棧。python traceback - 性能問題

爲此,我們使用traceback.extract_stack()來提取python的調用堆棧。 當稍後發生異常時,我們在每個元素上使用traceback.format_list(abc)來格式化和打印堆棧跟蹤。

問題是功能extract_stack太慢了。我將代碼從1.7秒減慢到11秒。

是否有任何函數來存儲堆棧跟蹤,以便以後能夠使用/打印? stacktrace getter必須非常快。格式化功能可以很慢,這是沒有問題的。

例子:

Stack Trace: 
    - LXScript: '_LXS:TOOL:RUNLX' 
     File "_LXS:TOOL:RUNLX", line 13, in <module> 
     File "lxs", line 1, in <module> 
    - UNIFACE ACTIVATE: 'ACTQREC_SVC' 'EXECLXSRP' 
    - LXScript: '_DATATRT:ACTQREC:[email protected]:run' 
     File "_LXS:TOOL:RUNLX", line 13, in <module> 
     File "lxs", line 1, in <module> 
     File "<string>", line 63, in run 
     File "<string>", line 97, in __doAll 
     File "<string>", line 127, in __do 
     File "_DATATRT:ACTQREC:EXECUTE", line 7, in do 
    - UNIFACE ACTIVATE: 'ACTQ_CSVC' 'EXECBYREC' 
    - LXScript: 'TOOL:ACTQ:[email protected]:runOnBeforeExec' 
     File "TOOL:ACTQ:SYNLAB_DATA", line 1, in <module> 
    ImportError: No module named 'localls' 
+1

爲什麼不在異常之後獲取堆棧跟蹤,所以開銷只在特殊情況下? –

+0

也許你可以使用'limit'參數來獲取上下文的一部分。在上面的例子中,也許你不需要所有的堆棧,但只需要5個更深的調用。應該加快一點操作。 –

+0

@PeterWood 因爲當我們從非python代碼(uniface)進入c接口時,我們沒有現有的stacktrace。 –

回答

1

我解決了這個問題!

我們可以使用stt_obj = sys._getframe().f_back來得到「<frame>?」然後我們可以使用estt_obj = traceback.extract_stack(f=stt_obj)traceback.format_list(estt_obj)將堆棧跟蹤作爲字符串列表。

+0

您能否顯示'elem'和'self'存在哪裏來讀取'STT_OBJ'? – Glycerine

+1

我編輯了我的答案@Glycerine –

+0

非常感謝你 - 這真的很有用,'f'是一個框架!我希望在文檔中更清楚 – Glycerine