Domino 6應用程序性能優化指南(第二部分)

 

  前臺/後臺編程

  當談到編程時,我們簡單的區別有時也稱爲的前臺程序和後臺程序。前臺程序是從應用程序的用戶界面(UI)運行的程序,例如,從操作菜單手動運行一項代理。這類程序的優勢在於易於診斷,因爲您可以通過手工測試很容易地確定程序運行良好和低效率運行。前臺程序的性能問題經常與字段、按鈕、代理相關-某些您可以更改的UI元素。正如在第一篇文章中建議的,一個良好的測試環境可以幫助您隔離這類故障。

  後臺程序是在後臺運行的程序。這包括預定的代理,它不時成爲與系統性能相關的故障的來源。例如,您可能擁有一個清除數據庫保存/複製衝突的預定的代理,您可能發現該代理在不正常的時間範圍內完成其任務,或者它消耗大量紊亂的系統資源來完成這一項任務。要測試後臺程序,審視您的日誌是否異常,如完成一項任務的長時間流逝。如果您正在測試的後臺程序是代理,檢查代理日誌,查看代理是如何很好地完成其任務的。

  現在,我們區分了前臺程序和後臺程序,那麼我們討論一些影響這兩者性能的常見程序錯誤。

  臨時變量

  編程時開發人員最容易犯的一個錯誤是不能使用臨時變量作爲檢索昂貴的數據的佔位符。最明顯的一個例子是依靠@DbLookup 公式結果的程序。如果您的程序使用要查找多次的數據,那麼將該數據設爲局部變量。現在您可以根據需要多次使用這一數據,包括:

  檢查錯誤條件時

  將數據分解成更小的單元時(例如,多值列表)

  對數據進行排序時

  另一個典型例子是擁有大量數據和用戶的文檔,用戶可以通過點擊按鈕,以不同的方式對數據進行排序。這種功能旨在模似懸浮的視圖排序功能,但發生在文檔的大表格內部。很明顯,這是一個將您的大量數據設爲局部變量,然後對局部變量進行排序的恰如其分的環境。它帶來的性能方面的差異令人驚訝。在作者過去需要花費一分多鐘時間來運行的程序通過局部變量的使用降低到一秒內。

  最後,第三個例子是查找數據庫中特定名稱的視圖的程序。您可能被通過db.views 屬性進行循環所吸引,但您可以通過第一次設定局部變量,如 viewLIST = db.views 來縮短程序運行時間,然後您可以反覆使用該臨時變量以實現最佳的性能。

  計算字段

  限制文檔中計算的次數可以提升性能。文檔中計算執行的次數越多,程序運行的速度就越慢。無論什麼時候您以讀模式打開一份文件,系統要進行一些計算。當您以編輯模式打開一份文件,或從讀模式切換到編輯模式時,系統要進行其它計算。用戶應該瞭解以讀模式打開文件和以編輯模式打開文件所用時間的比例,從而確定要減少的字段/計算。以下介紹每種情況的一些例子:

  如果文件經常讀取,而不是編輯@If(@IsDocBeingEdited; @DbColumn("Notes"; ""; ViewName; 1); kList)

  如果文件經常讀取,然後切換到編輯模式

  在這種情況下,確保您阻止執行的任何程序(如前面所述)在切換到編輯模式之後開始執行。例如,當用戶以讀模式打開文件時使用 @DbLookup 或 @DbColumn 公式的關鍵性字段爲防止運行的首要候選對象。但如果用戶將文件切換到編輯模式,使用 postModeChange 事件強迫文件刷新(例如, if source.editmode then call source.refresh )。此外,選擇關鍵性字段選項"文件刷新選項。" 在選定該選項之後,當用戶從讀模式切換到編輯模式時,文件自動刷新一次並強迫關鍵性字段重新求值。

Domino 6應用程序性能優化指南(第二部分)

  如果文件經常以編輯模式打開

  在這種情形下,您可以希望儘可能多的把昂貴(性能方面)的程序轉移到按鈕中,從而頻繁的編輯不會陷入困境。這假設即使在編輯文件時,大多數用戶不需要更改所有關鍵性字段。

  您可能認爲上述建議需要更多的計算,而不是少數計算。從某種意義上講,這是對的。只有採用這些步驟才能避免昂貴的計算,如@Db 公式,同時不用括號把簡單的 @properCase 的括起來,例如使用 @If(@IsDocBeingEdited) 。它不值得做。

  刷新字段值

  通過選擇表格屬性對話框表格信息標記上的自動刷新字段選項,您可以設置字段值爲自動刷新。

Domino 6應用程序性能優化指南(第二部分)

  這樣做會對您的性能產生負面影響,因爲每次用戶把鼠標移到表格字段時所有以前的字段都重新計算。這一繁重計算的目的是首先檢查Input Translation和Input Validation公式,但實際上所有程序都運行。

  當用戶選擇特定值時,如果您需要刷新計算的字段中的關鍵字表,選擇字段屬性對話框控制標記上的"當關鍵字改變時刷新域"選項。例如,假設您在表格中有多個關鍵字字段,關鍵字字段二、三和四的值不同,取決於用戶在關鍵字字段一中選擇的值。在這種情況下,使用"當關鍵字改變時刷新域"功能。這就像按下F9鍵一樣,只是每次這一關鍵字字段中的值更改後它自動運行。這提供了勝過表單對話框中"自動刷新域"選項的性能,因爲文檔只在第一個關鍵字字段中的值更改後才刷新,而不是任何值更改後都刷新。注:您必須爲其它關鍵字字段設置字段選項"當文檔刷新時刷新選擇"。任何無需參與這一動態關係的關鍵字字段無需設置這一項功能,因此當第一個關鍵字字段的值更改後它們無需刷新。

Domino 6應用程序性能優化指南(第二部分)

  使用"創建時計算"的域類型

  當用戶創建文檔時創建時計算計算字段的值。您可以使用創建時計算來延續這些值,或者如果某些其它程序將設置一個字段,但您希望它保留原值。例如,響應文件中名爲OriginalSubject的字段包含公式Subject。如果用戶創建響應文件,該字段沿襲選定的主文件,再也無需計算。另一個例子是稱爲DateClosed的字段,它由運行操作條上按鈕的程序代碼。由於從未想過這一字段更改自己的值,我們將其設爲創建時計算並使用公式DateClosed。這使其可以做爲佔位符公式來運行。它只在第一次計算時才嘗試計算(在這種情況下,我們假設無沿襲值在使用),此後只採用強行輸入的值。注: 只要用戶保存了文件,創建時計算的域向輸入到其中的值應用正確的數據類型。

  您可能會問,在這兩個例子中使用創建時計算的域 和計算域 有什麼區別。主要的區別很簡單,每次編輯、刷新和保存文件時計算域都計算,即使它沒有真正的工作要執行也是如此。如果有大量與上述一樣簡單的公式,那麼這一字段類型會給您的應用程序的性能帶來稍許差異。但是,如果在您的表單中有許多類似的字段,您將看到性能方面的差異。在此例中,由於設置這一字段爲計算字段不會帶來任何優勢,您的用戶可以獲得更好的性能。一個真正不勞而獲的例子!

  緩存和非緩存參數

  緩存和非緩存參數適用於所有@Db公式。如果您規定了緩存參數,公式值將被保存到緩存中以便於檢索。如果您規定了非緩存參數,公式值將不被保存到緩存中,因此每次查找都基於數據庫來進行。開發人員經常超額使用非緩存參數並且更多的資源用於從數據庫檢索數據而不是從緩存。不要對您認爲重要的數據使用非緩存參數。

  用戶反而考慮數據更改的程度:數據更改得越頻繁,您就越想使用非緩存參數。對於不頻繁更改的數據,使用緩存參數。例如,假設您有一個討論數據庫,其中用戶可以使用規定的關鍵字,它們創建了新類別。(也就是每次用戶創建新主題時,他或她可以爲該主題規定任何類別。)在這種情況下,這類數據可能相對不重要,但您仍然需要使用非緩存參數,從而在一行中輸入兩個或三個主題的用戶發現新類別在下一主題的關鍵字字段中立即反映出。爲了提高性能,使用非緩存參數和ODBC訪問:"在索引中產生唯一的關鍵字"選項,它已經在 第一部分中討論過。記住:"在索引中產生唯一的關鍵字"選項只列出唯一的類別來維護一個較小規模的視圖索引。

Domino 6應用程序性能優化指南(第二部分)

  舉一個反例,假設您查找薪水信息。這是一類至關重要的信息,但是,通常每隔幾個月薪水纔會更改一次,從而使這類數據成爲緩存的一個很好的候選對象。

  LotusScript方法

  Lotus測試來確定在獲得一組文檔方面,誰是表現最好的最常使用的LotusScript 方法-實際上在LotusScrip任何部分程序代碼中最常運行的任務。在這一小節,我們比較以下常用的LotusScript方法:

  db.FTSearch

  db.Search

  view.GetAllDocumentsByKey

  view.GetDocumentByKey

  在這類測試過程中,使用不同大小的數據庫(10,000、100,000和1,000,000份文檔)來了解每種方法是如何很好地運行的。

  db.FTSearch方法

  在對數據庫的全文檢索後,db.FTSearch返回文檔集合。它運行良好,但需要當前的全文索引,也許對語法更深入的瞭解。此外,根據服務器的Notes.ini 設置,對返回的文件集合的大小施加了限制。當然,如果您的查找是基於多文本字段的內容,那麼這是您唯一切實可行的選擇。

  db.Search方法

  在使用視圖選擇公式進行數據庫查找之後,db.Search返回文檔集合。對於大數據庫中的小規模集合來說這是相對低效率的執行程序。例如, 如果您的數據庫中有100,000份文檔並且您只需查找5或10份文檔,您可能希望避免使用db.Search。在另一方面,它不需要全文索引和預先創建的視圖,因此它是一種非常方便的查詢方法。例如,如果您對幾乎不能控制的數據庫進行查詢,這可能是您唯一可靠的選擇。

  從Release 5開始,這種方法成爲檢索文件集合最快的方式。唯一的缺點是需要建立相關的視圖。但是,只要您精簡了您的視圖設計和不使用昂貴的時間/日期敏感的公式(正如第一部分所討論),這些視圖對性能和磁盤空間的影響應可以降低以最小,程序使用view.GetAllDocumentsByKey從這些視圖獲得文件集合的速度將非常迅速。

set doc = DocumentCollection.GetNextDocument ( doc )

  其中i從1增加到DocumentCollection.count。 對於文檔小集合來說-和對於單獨運行的程序來說,如預定的代理-性能下降爲最小,但對於文檔大集合來說-或者許多用戶同時運行的程序來說會影響性能,它使GetNth成爲不明智的選擇。GetNth方法通常適用於您想要從集合中挑選文檔的情形,而不是簡單地遍歷整個集合。

  view.GetDocumentByKey方法

  這是唯一一種不將一組文檔保存到內存中的方法。view.GetDocumentByKey而是使用已經構建的視圖索引作爲其集合並且一次只把一份文檔放到視圖中。這種方法與view.AutoUpdate = False一同使用,它非常迅速且不需要內存來保存可能的大文件集合。

  注:如果前一份文檔已經從視圖中刪除,當有機會訪問視圖中的下一文檔時,view.AutoUpdate = False主要用於避免錯誤信息,但它還可以顯著提升性能以便運行代理。當更改文檔中的數據時,使用view.AutoUpdate = False您會看到視圖中有顯著的改進。

  事件、共享的要素和其它

  以下是必須記住的一些編程注意事項:

  注意表單中事件的數量,不要"overcode"

  當刪除程序時,注意完全刪除它。不要只是重新標記它爲刪除,或者部分刪除程序。您可以根據circle/squiggle是填滿還是清空來告訴事件是否有程序代碼。

  共享的要素是低效率的執行程序,但是它們可以在多個位置使用,從而彌補了其糟糕的性能。

  使用共享的元素來保存某些工作以及重複一個要素來提升性能時仔細考慮。

  如果您實施了錯誤檢測,確保當遇到錯誤時檢測停止。

  在精心編程的情形下,通過當它邏輯上應結束時使其繼續運行,這可以確保您的程序不會"漏掉"。

  大規模的子表單是低效率的執行程序。

  大規模的子表單會影響應用程序的性能。如果您在應用程序中未多次使用大規模的子表單,考慮在每個表單中重複這類字段,而不是使用子表單。

  使用較少的字段。

  在文檔中使用較少的字段與性能相關,而不是文檔的大小。使用具有較多數據的較少字段,如多值字段,而不是使用較少數據的比較多的字段可以提升應用程序的性能。由於許多傳統的編程人員對Notes/Domino應用程序開發不熟悉,這可能一些概念直觀,但實際測試很明顯地驗證了這一概念。

  使用view.Autoupdate=False 來阻止視圖刷新。

  正如前面介紹,同時使用 view.GetDocumentByKey 方法和這一屬性可以是高效率的執行程序。

  使用StampAll方法來立即修改大量文檔。

  當您需要使用靜態值來標記大量文檔時這種方法極其有效,如當前日期/時間或值的標記集。

  ForAll 語句是遍歷循環的最快方法。

  固定數組是比動態數組更卓越的執行性能。

  動態數組是比固定數組稍微低效率的執行性能,但動態數組的規模恰如其分,在您選擇固定還是動態數組之前請預以權衡。

  結語

  我們希望這些注意事項對您有所幫助,在實施這些方案之後您將會很快看到應用程序性能方面的改進。我們希望能夠聆聽到您的應用程序性能調整的最佳方案,因此如果您有任何好的建議並且希望與廣大的Notes/Domino應用程序開發人員共享,請提交給我們。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章