2017-08-15 60 views
1

Github頁面,它說:Typesafe的scala-logging與其他日誌框架相比性能如何?

它是高性能的,正是因爲有了斯卡拉宏啓用檢查,成語應用併產生下面的代碼:

if (logger.isDebugEnabled) logger.debug(s"Some $expensive message!") 

如何比Play的日誌記錄更高效嗎?

在玩,它封裝了底層的記錄有自己的電話,如果調試在常規代碼啓用只檢查,沒有宏參與:

def debug(message: => String)(implicit mc: MarkerContext): Unit = { 
    if (isDebugEnabled) { 
    mc.marker match { 
     case None => logger.debug(message) 
     case Some(marker) => logger.debug(marker, message) 
    } 
    } 
} 

(源代碼是here

如何正在檢查通過宏啓用調試是否使其更具性能?

+0

它說它比其他東西更「高效」嗎? – JohnnyAW

回答

2

讓我們考慮一個簡單的方法:

def debug(message: => String): Unit = { 
    if (logger.isDebugEnabled) { 
    logger.debug(message) 
    } 
} 

這裏,這個方法接受一個通過名字參數並調用它,只有當啓用了調試。在內部,所有的名稱參數映射到零元的功能,所以此方法等同於以下之一:

def debug(message:() => String): Unit = { 
    if (logger.isDebugEnabled) { 
    logger.debug(message()) 
    } 
} 

這意味着每次調用此方法在你的代碼中創建一個新功能情況。也許編譯器有時可以優化它,但絕對不總是。在一般情況下,調用由名調用方法需要建立功能類的實例內部,如果你捕捉任何變量,這是幾乎總是:

logger.debug(s"Something interesting happened: $something. Message: $message") 

那麼這個函數對象,是一個封閉,也將包含引用到這些捕獲的變量。

與此相比,基於宏觀的方法將字面上改寫成健康檢查和底層調用記錄:

logger.debug(s"Something interesting happened: $something. Message: $message") 
// gets rewritten to 
if (logger.logger.isDebugEnabled) { 
    logger.logger.debug(s"Something interesting happened: $something. Message: $message") 
} 

這樣,沒有創建額外的對象;代碼就會像你明確地寫出來一樣工作,除了你不必真的寫這個樣板。

+0

據我瞭解,字符串是否是按名稱調用,只要它傳遞給'debug()'方法,所有捕獲變量將被評估,不管它是否是宏。一樣的去無功功能。宏只是生成包裝if語句。它並沒有消除任何這些東西。 我還是不明白 –

+0

如果OP的示例中使用了'String'不是按名稱值都在宏的使用和定期的呼叫,如果檢查將是相同的。 –

+0

@OriPopowski,不,這個宏確實消除了即將建立的'Function0'對象,該對象總是爲名稱參數構造的。使用宏,你根本就沒有它,因爲它會將方法調用重寫爲'if'語句。 –