android - 从 android 资产中解析微小的 JSON 非常慢
问题描述
我正在用 Kotlin 编写一个简单的 Android 应用程序,它将向用户显示按类别划分的祈祷。assets 文件夹中有 5 个 JSON 文件,每个文件只有大约 10 KiB。
我使用 Klaxon 将 JSON 文件解析为这两个数据类:
data class Prayer(val prayerName: String, val verseTitle: String, val verseBody: String,
val prayerLine: String, val prayerBody: String, val prayerEnding: String)
data class PrayerCategory(val title: String, val bgImage: String, val headerImage: String,
val prayers : List<Prayer>)
这是我用于解析祈祷的代码:
private fun loadPrayerNames(jsonFile: String) {
val millis = measureTimeMillis {
val input = assets.open("${jsonFile}.json")
val prayerCategory = Klaxon().parse<PrayerCategory>(input)
if (prayerCategory != null) {
for (prayer in prayerCategory.prayers) {
val prayerName = prayer.prayerName
prayersMap[prayerName] = prayer
}
}
}
println("Loading prayer category took $millis ms.")
}
如您所见,资产只有一种访问权限。没有 assets.list(),没有废话。正如你所注意到的,我已经测量了时间..让你猜猜..这是调试输出:
加载祈祷类别花费了 3427 毫秒。
是的,没错。加载和解析 10KiB 大 JSON 花了3.5 秒!我重复。不涉及火箭科学。只需解析 10 KiB JSON。3.5秒……嗯……
顺便说一句,我正在诺基亚 6.1 上测试它,这是一款非常活泼的手机。
所以..我的问题:
- 是什么导致了这种行为?
- 除了建立一个存储大约 50 个祈祷的数据库之外,还有什么方法可以加快速度?
我将非常感谢您的帮助!
解决方案
在性能方面,Android 资产似乎名声不佳。但是,我的测试证明,在这种情况下,是 Klaxon 库负责。
在 Klaxon 中发现主要性能问题(请参阅https://github.com/cbeust/klaxon/issues/154)后仍未修复,我尝试了推荐的替代方案:Moshi(https://github.com/square/莫西)。
Moshi 确实提高了性能,但解析我的 JSON 仍然需要大约 1 秒。
在这些实验之后,我求助于使用 JSONObject 的老式解析:
data class Prayer(val prayerName: String, val verseTitle: String, val verseBody: String,
val prayerLine: String, val prayerBody: String, val prayerEnding: String) {
companion object {
fun parseJson(json: JSONObject) : Prayer = Prayer(json.getString("prayerName"),
json.getString("verseTitle"), json.getString("verseBody"),
json.getString("prayerLine"), json.getString("prayerBody"),
json.getString("prayerEnding"))
}
}
data class PrayerCategory(val title: String, val bgImage: String, val headerImage: String,
val prayers : List<Prayer>) {
companion object {
fun parseJson(json: JSONObject): PrayerCategory {
val prayers = ArrayList<Prayer>()
val prayersArray = json.getJSONArray("prayers")
for(i in 0 until prayersArray.length()) {
prayers.add(Prayer.parseJson(prayersArray.getJSONObject(i)))
}
return PrayerCategory(json.getString("title"), json.getString("bgImage"),
json.getString("headerImage"), prayers)
}
}
}
这将解析时间从 3427 毫秒减少到 13 毫秒。结案。;-)
推荐阅读
- c++ - 如何阻止我的代码读取下一个字符?
- webpack - 在 CRA 中运行测试时无法包含 css?
- r - PMCID表行到列形式的解析
- mysql - Kubernetes 上的 PVC 如何与 MYSQL 协同工作?
- r - 来自 rstatix 的 anova_test 出现无法解释的错误
- javascript - Vue选择值
- javascript - 当其余应该是MaterialUI Grid中的列时,如何将两个项目作为行放在一列中?
- javascript - 如何根据其位置放置可拖动项目
- php - PHP / Laravel:如何处理 SSE 流并解析获取的数据
- css - 有没有办法在 sass 中确定第三方 css 的范围?