在编程调试和定位问题的时候,日志是一个最常用的工具。比如输出一些信息,确定执行轨迹。今天我们这里简单聊一聊打印日志的一些分析。
通常,我们进行日志输出的时候都会限定在debug包下执行,对于非debug包,我们就不输出日志。那么如果是非debug,不同的日志输出方式可能存在一定的性能问题,本文将通过几个版本来对比着方面的差异。
这可能是最原始的版本打印日志了,判断是否是debug,然后决定是否输出日志
1 2 3 4 5 6 7 8 9 | fun debugLog(message: String?) { if (BuildConfig.DEBUG) { Log.d("debugLog", message) } } private fun testDebugLog() { debugLog("getProperties " + getProperties()?.joinToString()) } |
---|
上面的问题
testDebugLog
需要执行getProperties()
,这一步的性能不可预知testDebugLog
内部存在字符串拼接非Debug条件下
存在一定的运行时开销既然拼接会导致一些问题,那么下面的版本采用(调用处)不拼接的形式
1 2 3 4 5 6 7 8 9 | fun debugMessage(vararg args: Any?) { if (BuildConfig.DEBUG) { Log.d("debugMessage", args.joinToString()) } } private fun testDebugMessage() { debugMessage("getProperties", getProperties()) } |
---|
getProperties()
**,这一步的性能不可预知**getProperties
,另一个元素是getProperties()
的内容在非Debug条件下
仍然存在一定的运行时开销,不完美。这个版本是相对最好的实现,规避了非Debug环境下的字符串拼接和具体求值的操作
1 2 3 4 5 6 7 8 9 10 11 | inline fun smartMessage(lazyMessage: () -> Any?) { if (BuildConfig.DEBUG) { Log.d("smartMessage", lazyMessage().toString()) } } private fun testSmartMessage() { smartMessage { "getProperties " + getProperties() } } |
---|
当我们反编译Kotlin 代码 到 Java代码时,一切就清晰了。
1 2 3 4 5 6 7 8 9 10 | private final void testSmartMessage() { int $i$f$smartMessage = false; if (BuildConfig.DEBUG) { String var3 = "smartMessage"; int var2 = false; String var4 = "getProperties " + this.getProperties(); Log.d(var3, String.valueOf(var4)); } } |
---|
smartMessage
提取到调用处testSmartMessage
BuildConfig.DEBUG
成立时才执行,否则不执行