如何提高遍歷pocoui樹的效率
工作中經常碰到需要遍歷pocoui樹的情況。不同的寫法差別很大,寫個部落格記錄一下。
poco的例項,儲存了整個專案的ui樹,體積可能非常大。
以我手頭的專案為例,其完整的ui樹,以字典形式存在txt文字裡,容量高達272k。
poco樹中的各種控制項都有其屬性,下面就以這個「uicarmeraroot」物件為例進行各種寫法的效率比對。
在對該poco例項進行操作前,先簡單對其遍歷一遍,看看耗時多少。
可知:遍歷乙個272k的字典,python只需要0.48秒。
1.offspring()
查詢ui樹里,最偷懶的寫法就是直接生成乙個全樹的例項,然後取其所有後代,再在其後代中逐個查詢符合條件的屬性對應的物件。
示例**為:
uioffspring=poco("uiroot(clone)").offspring()
for x in uioffspring:
if x.attr("name") == 'uicameraroot':
print(x.get_text())
print('查詢控制項過程結束')
break
else :
print("沒找到")
然後這段**執行所需時間為:144秒。
分析一下,瓶頸應該出在if x.attr("name") == 'uicameraroot':
這句。
每次對poco例項的屬性進行操作,都要重新生成乙個dump,這非常耗費資源。
除非在之後的業務邏輯裡要對offspring()進行不可同步的操作,否則不要採取這種方法。
2.offspring()指定引數
offspring方法裡跟指定引數,可以將dump操作縮減為1次。大大提公升效率。
示例**如下:
ui_node_name = poco("uiroot(clone)").offspring(name='uicameraroot')
print('查詢控制項xx結束')
**精簡,效率也提公升了幾十倍。花費了4.8秒就從整個ui樹中查詢到了我們需要的控制項。
poco提供了freeze方法能再次加快查詢效率。
從freeze的原始碼可以看到,freeze()得到的是當前poco例項的乙個靜態副本。
我們可以通過下面的方式取到freeze例項。
freeze=poco.freeze()
hierarchy_dict = freeze.agent.hierarchy.dump()
print(hierarchy_dict)
嘗試將之前的方法1和方法2,用到這個freeze例項上,
即將方法1裡的
uioffspring=poco("uiroot(clone)").offspring()
替換為
uioffspring=freeze("uiroot(clone)").offspring()
方法2 裡的
ui_node_name = poco("uiroot(clone)").offspring(name='uicameraroot')
替換為
ui_node_name = freeze("uiroot(clone)").offspring(name='uicameraroot')
看看結果會如何?
兩種演算法的耗時相差無幾。且都低於對poco例項的操作耗時。
當然,freeze也不是沒有缺點的,它是poco例項的靜態物件,當poco發生變動時,不會實時更新。所以每次操作前,盡量重新凍結賦值;使用完最好也盡快釋放,否則會佔據大量的記憶體資源。
結論
除非需要操作整個ui樹例項裡的不同物件,否則盡量不要讀取全樹;讀全樹的效率比讀單個控制項的效率低2個數量級。
freeze的效率極高。但需要手動重新整理。
樹的遍歷 樹的遍歷(PTA)
給定一棵二叉樹的後序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這裡假設鍵值都是互不相等的正整數。輸入第一行給出乙個正整數n 是二叉樹中結點的個數。第二行給出其後序遍歷序列。第三行給出其中序遍歷序列。數字間以空格分隔。在一行中輸出該樹的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多餘空格。7 2...
Map遍歷效率比較
1 由來 上次部落格提到了map的四種遍歷方法,其中有的只是獲取了key值或者是value值,但我們應該在什麼時刻選擇什麼樣的遍歷方式呢,必須通過實踐的比較才能看到效率。也看了很多文章,大家建議使用entryset,認為entryset對於大資料量的查詢來說,速度更快,今天我們就通過下面採用不同方法...
Map遍歷效率比較
原博 1 由來 上次部落格提到了map的四種遍歷方法,其中有的只是獲取了key值或者是value值,但我們應該在什麼時刻選擇什麼樣的遍歷方式呢,必須通過實踐的比較才能看到效率。也看了很多文章,大家建議使用entryset,認為entryset對於大資料量的查詢來說,速度更快,今天我們就通過下面採用不...