从 android 资产中解析微小的 JSON 非常慢
Parsing tiny JSON from android assets is incredibly slow
我正在用 Kotlin 编写一个简单的 Android 应用程序,它将向用户显示分为几类的祈祷。资产文件夹中有 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(),没有废话。
正如你所注意到的,我已经测量了时间..让你猜测..这是调试输出:
Loading prayer category took 3427 ms.
是的,没错。加载和解析 10KiB 大 JSON 花了 3.5 秒! 我重复一遍。不涉及火箭科学。仅解析 10 KiB JSON。 3.5秒.....嗯..
顺便说一句,我正在诺基亚 6.1 上测试它,它非常活泼 phone。
所以..我的问题:
- 是什么导致了这种行为?
- 除了建立一个数据库来存储大约 50 个祈祷之外,还有什么方法可以加快速度吗?
非常感谢您的帮助!
Android 资产在性能方面似乎声誉不佳。然而,我的测试证明,在这种情况下,是 Klaxon 图书馆负责。
在 Klaxon 中发现主要性能问题后(参见 https://github.com/cbeust/klaxon/issues/154), which is still not fixed, I have tried recommended alternative: Moshi (https://github.com/square/moshi)。
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 毫秒。结案。 ;-)
我正在用 Kotlin 编写一个简单的 Android 应用程序,它将向用户显示分为几类的祈祷。资产文件夹中有 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(),没有废话。 正如你所注意到的,我已经测量了时间..让你猜测..这是调试输出:
Loading prayer category took 3427 ms.
是的,没错。加载和解析 10KiB 大 JSON 花了 3.5 秒! 我重复一遍。不涉及火箭科学。仅解析 10 KiB JSON。 3.5秒.....嗯..
顺便说一句,我正在诺基亚 6.1 上测试它,它非常活泼 phone。
所以..我的问题:
- 是什么导致了这种行为?
- 除了建立一个数据库来存储大约 50 个祈祷之外,还有什么方法可以加快速度吗?
非常感谢您的帮助!
Android 资产在性能方面似乎声誉不佳。然而,我的测试证明,在这种情况下,是 Klaxon 图书馆负责。
在 Klaxon 中发现主要性能问题后(参见 https://github.com/cbeust/klaxon/issues/154), which is still not fixed, I have tried recommended alternative: Moshi (https://github.com/square/moshi)。
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 毫秒。结案。 ;-)