从 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。

所以..我的问题:

  1. 是什么导致了这种行为?
  2. 除了建立一个数据库来存储大约 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 毫秒。结案。 ;-)