前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >这可能是最好的 Android/Kotlin日志输出方法

这可能是最好的 Android/Kotlin日志输出方法

作者头像
技术小黑屋
发布2020-01-22 22:33:09
2.3K0
发布2020-01-22 22:33:09
举报
文章被收录于专栏:技术小黑屋技术小黑屋

在编程调试和定位问题的时候,日志是一个最常用的工具。比如输出一些信息,确定执行轨迹。今天我们这里简单聊一聊打印日志的一些分析。

通常,我们进行日志输出的时候都会限定在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 内部存在字符串拼接
  • 如果拼接内容复杂,比如一个庞大的Object,会造成一定的开销
  • 综上所述,该实现如果在非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()**,这一步的性能不可预知**
  • 上面的代码使用了可变参数的形式处理message信息
  • 而可变参数内部实际采用了数组的形式,也就是上面的代码会在运行时生成一个数组,一个元素是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() } }

  • 上面使用了Lambda表达式来生成message信息

如何巧妙地规避不必要的开销

当我们反编译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)); } }

  • 之前的Lambda 由于采用了 inline 处理 会把smartMessage 提取到调用处testSmartMessage
  • 上面的信息,都是确保了在BuildConfig.DEBUG成立时才执行,否则不执行
  • 上面的做法,利用了Kotlin的特性,就运行时可能存在的开销一下就移除了。

注意

  • smartMessage 建议只在 Kotlin 中调用,否则会生成实例,因为无法inline处理

相关阅读

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原始版
  • 不拼接的版本
  • 相对最完美的版本
    • 如何巧妙地规避不必要的开销
    • 注意
    • 相关阅读
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档