【发布时间】:2021-08-28 06:21:19
【问题描述】:
我必须在 Android 中反序列化一个 Json 对象,其中包含一个巨大的 Int Json 数组。
架构是这样的:
{
"key1": "value1",
"key2": "value2",
"smallObject": {
"key": "value"
},
"smallArray" [
{}, {} ,{}
],
"hugeObject": {
"data": {
"hugeIntArray": [
-1, -1, 1, 2, -1 ...
]
},
"key": "value"
}
}
hugeIntArray数组的长度可以超过200万,使得JSON文件大于15MB。
我尝试用 Gson 解析,需要 7 秒,还有 Moshi,需要 11 秒。
我发现 Moshi 可以通过自定义 JsonAdapter 和序列进行延迟加载。但我无法将它应用到我的架构中。
我的目标是像序列或流一样使用它来将 int 值转换为图像的像素。
【问题讨论】:
-
没有一个好的答案,因为你使用了错误的工具。不要像那样使用二进制数据序列化/反序列化:它会浪费流量和资源。我猜你至少需要一个字节数组(我猜你的 int 数组不会有非字节值)。提前知道字节数组的长度会非常好,通过添加诸如hugeIntArrayLength/hugeByteArrayLength之类的东西来减少中间数组分配的数量(否则Gson或Moshi怎么能提前知道最终长度?)。
-
在 JSON 中打包二进制数据通常是一个坏主意,有更多不这样做的原因。即使按照下面的建议将其编码为 Base64 编码的字符串也是一个坏主意:读取巨大的字符串会使您的设备承受中间对象分配的压力。另一件事是,如果您使用的是 Web 套接字,则 WS 使用者应该只使用消息(可能尽可能快:不建议使用巨大的数组)。
-
这里最好的选择是完全拒绝像JSON那样发送二进制数据的想法,而是放置引用二进制数据的资源URL而不是巨大的数组,并且仅在确实需要时才加载此类资源.结果:您的应用将使用更少的内存,从 Gson/Moshi 的角度来看,它会运行得更快,它会按需加载链接的资源(可能以优化的方式)等等。