我有一個靜態日誌記錄功能,它使用StringBuilder在將字符串發送到日誌之前連接一堆查詢參數。這個過程可能會適度地延長,因爲我們可能有〜10個參數(接通電話),最終長達200個字符。儘量減少事件記錄的性能影響?
我想盡量減少日誌功能對性能的影響。 (這個日誌記錄功能可能每個Web請求被多次調用,並且我們測量每個Web請求的處理時間)
How/Should /我可以構建一個StringBuilders「池」來提高性能嗎?
我也可以異步執行所有這些日誌記錄,對不對?我應該怎麼做?
我有一個靜態日誌記錄功能,它使用StringBuilder在將字符串發送到日誌之前連接一堆查詢參數。這個過程可能會適度地延長,因爲我們可能有〜10個參數(接通電話),最終長達200個字符。儘量減少事件記錄的性能影響?
我想盡量減少日誌功能對性能的影響。 (這個日誌記錄功能可能每個Web請求被多次調用,並且我們測量每個Web請求的處理時間)
How/Should /我可以構建一個StringBuilders「池」來提高性能嗎?
我也可以異步執行所有這些日誌記錄,對不對?我應該怎麼做?
由於記錄通常是狀態依賴後,把日誌條目的實際建設小康到另一個線程通常不是一個選項。但是,您可以捕獲相關數據以異步格式化。雖然我不會在這裏實現整個記錄機制(雖然你可以看到我的ProcessQueue article on CodeProject的東西,這將使它更容易),你可以做這樣的事情:
public static void LogAsync<T1>(T1 value, Func<T1, string> formatter)
{
// asynchronously call formatter(value) and log the result
}
public static void LogAsync<T1, T2>(T1 value1, T2 value2, Func<T1, T2, string> formatter)
{
// asynchronously call formatter(value1, value2) and log the value
}
...and so on
如果字符串建設是什麼陷入泥淖的然後(假設各種T
類型是不可變的,或者至少不會在調用LogAsync
的調用和當調用formatter
時),這應該減輕這種情況。
如果預計伐木活動的爆發,如果該事件實際登錄導致你已經測量的性能問題(見Premature Optimization下優化/設計水平的「級別」),您可以創建日誌請求和隊列單獨的線程在隊列中運行。如果隊列已滿,您可能希望隊列阻止呼叫者,直到隊列變滿爲止。
如果你的日誌請求相當穩定而不是活動爆發,如果通常有一個CPU核心沒有被使用,你仍然可以獲得整體性能。如果所有的CPU核心通常都被大量使用,那麼單獨的線程只會增加開銷和複雜性而不提供好處。
問題是我需要在發送到隊列之前從對象中提取一個字符串。 (已經設置) – 2010-04-21 17:07:53
爲什麼不把對象放在隊列中? – 2010-04-21 17:10:45
隊列只接受字符串。 – 2010-04-21 18:27:39
您可能需要的是您的應用正在處理的每個HttpRequest的StringBuilder實例。一個簡單的方法是在Global.asax中創建這個StringBuilder。
你不應該在這個stringbuilder上擔心同步,因爲在任何時候它只能被一個httpRequest訪問。
當請求處理完成時,您將不得不將stringBuilder的內容推送到某個中心位置(日誌),並且您將不得不擔心同步,但是如果您將在OnEndRequest事件中執行該操作,影響將很小。
不要忘記清潔的StringBuilder你移動了它的內容以日誌
不,你不應該池StringBuilder對象。他們創造和使用便宜。如果你將它們集中在一起,你只需要把它們從短壽命的物體變成長壽命的物體。實際上,垃圾收集器將一個StringBuilder移動到下一代來保留它,而不是清理它們中的大部分。
使用StringBuilders絕對不是瓶頸。大部分工作將把字符串存儲在日誌中,無論它在哪裏。
以異步方式進行日誌記錄本身不會節省您的任何性能。服務器仍然需要做同樣的工作,並且只需添加創建另一個線程的開銷即可。
如果您保留一個要記錄的字符串緩衝區並同時存儲一堆字符串,可能會更有效。當然,存儲多個字符串實際上可以比存儲一個字符串更有效。
你可以在一個靜態變量中保存一個字符串列表,並且當你有足夠的字符串時將它們存儲起來。 (當然可以同步訪問,因爲有幾個線程可以訪問它。)或者簡單地從一個Web請求中收集字符串並保存到一個,這更容易,但仍然可以爲您節省一些工作。
我強烈建議使用日誌庫(如Nlog),在這些情況下它們非常靈活和高效,還可以專注於業務邏輯。感謝你可能認爲第三方圖書館會很慢,但這不是我的經驗,尤其是與Nlog。
另一種選擇是log4cpp,雖然這不是真的在開發中
我敢打賭,真正的性能影響是IO,而不是StringBuilder。 – Fernando 2010-04-21 17:26:25
我敢打賭,伐木根本不是真正的影響。 – 2010-04-21 18:35:14