Moshi Vs Gson Vs Kotlin Serialisation性能PK

图片

Moshi Vs Gson Vs Kotlin Serialisation

定义

  • • Gson

Gson 是一个Java序列化/反序列化库,用于将Java对象转换为JSON格式,以及将JSON格式转换回Java对象。

  • • Moshi

Moshi 是一个现代化的JSON库,适用于Android和Java。它使得将JSON解析为Java对象以及将Java对象转换回JSON变得简单。

  • • Kotlin序列化

Kotlin序列化是一种以Kotlin为主导的、在编译时类型安全、无反射且完全跨平台准备的序列化机制,用于将Kotlin对象转换为JSON或Protobuf等数据格式,反之亦然。该库不使用无反射,而是采用显式注解 @Serializable。应用该注解后,编译器插件会在伴生对象上添加一个特殊的函数 serializer(),返回类型为 KSerializer 的序列化器。KSerializer 对象实现了所需的接口,用于序列化和反序列化数据类。

性能比较

为了定义比较,创建了一个基准测试规则,可以总结如下代码片段:

class SerializableBenchMark {
    lateinit var json: Json
    lateinit var moshi: Moshi
    lateinit var gson: Gson
    lateinit var response: String
    private val context = InstrumentationRegistry.getInstrumentation().targetContext

    @Before
    fun setup() {
        json = Json {
            ignoreUnknownKeys = true
            isLenient = true
            encodeDefaults = false
            coerceInputValues = true
        }
        moshi = Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()

        gson = GsonBuilder()
             .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
            .setLenient().create()

        response = context.assets.open("sample_response.json").use {
            it.bufferedReader().readText()
        }
    }
    @get:Rule
    val benchmarkRule = BenchmarkRule()

    @Test
    fun exampleKotlinSerialisation() = benchmarkRule.measureRepeated {
        json.decodeFromString(Response.serializer(), response)
    }

    @Test
    fun exampleMoshi() = benchmarkRule.measureRepeated {
        val jsonAdapter = moshi.adapter(Response::class.java)
        jsonAdapter.fromJson(response)
    }

    @Test
    fun exampleGson() = benchmarkRule.measureRepeated {
          gson.fromJson(response, Response.javaClass)
    }
}
  • • 这里的 sample_response.json是从此链接构建的。https://www.covidvisualizer.com/api

结果

测试用例 1 — 基准测试

我已记录了每个测试用例对应的 benchmark-data.json 文件,以便进行比较。

设备详情

"build": {
            "brand": "vivo",
            "device": "2130",
            "fingerprint": "vivo/2130i/2130:12/SP1A.210812.003/compiler05210733:user/release-keys",
            "model": "V2130",
            "version": {
                "sdk": 31
            }
        },
        "cpuCoreCount": 8,
        "cpuLocked": true,
        "cpuMaxFreqHz": 2500000000,
        "memTotalBytes": 12146495488,
        "sustainedPerformanceModeEnabled": false
    }

Kotlin -Serialisation

"benchmarks": [
        {
            "name": "PROFILED_exampleKotlinSerialisation",
            "params": {},
            "className": "com.example.benchmark.SerializableBenchMark",
            "totalRunTimeNs": 12119030155,
            "metrics": {
                "timeNs": {
                    "minimum": 3.802098385E9,
                    "maximum": 3.802098385E9,
                    "median": 3.802098385E9,
                    "runs": [
                        3.802098385E9
                    ]
                },
                "allocationCount": {
                    "minimum": 19390.0,
                    "maximum": 19390.0,
                    "median": 19390.0,
                    "runs": [
                        19390.0,
                        19390.0,
                        19390.0,
                        19390.0,
                        19390.0
                    ]
                }
            },
            "sampledMetrics": {},
            "warmupIterations": 2310,
            "repeatIterations": 1,
            "thermalThrottleSleepSeconds": 0
        }
    ]

Moshi

"benchmarks": [
        {
            "name": "PROFILED_exampleMoshi",
            "params": {},
            "className": "com.example.benchmark.SerializableBenchMark",
            "totalRunTimeNs": 11961625309,
            "metrics": {
                "timeNs": {
                    "minimum": 3.531992307E9,
                    "maximum": 3.531992307E9,
                    "median": 3.531992307E9,
                    "runs": [
                        3.531992307E9
                    ]
                },
                "allocationCount": {
                    "minimum": 14509.0,
                    "maximum": 16854.0,
                    "median": 14509.0,
                    "runs": [
                        16854.0,
                        14509.0,
                        14509.0,
                        14509.0,
                        14509.0
                    ]
                }
            },
            "sampledMetrics": {},
            "warmupIterations": 1202,
            "repeatIterations": 1,
            "thermalThrottleSleepSeconds": 0
        }
    ]

Gson

"benchmarks": [
        {
            "name": "PROFILED_exampleGson",
            "params": {},
            "className": "com.example.benchmark.SerializableBenchMark",
            "totalRunTimeNs": 1331248385,
            "metrics": {
                "timeNs": {
                    "minimum": 1.76971077E8,
                    "maximum": 1.76971077E8,
                    "median": 1.76971077E8,
                    "runs": [
                        1.76971077E8
                    ]
                },
                "allocationCount": {
                    "minimum": 20.0,
                    "maximum": 20.0,
                    "median": 20.0,
                    "runs": [
                        20.0,
                        20.0,
                        20.0,
                        20.0,
                        20.0
                    ]
                }
            },
            "sampledMetrics": {},
            "warmupIterations": 1062,
            "repeatIterations": 1,
            "thermalThrottleSleepSeconds": 0
        }
    ]

从上面的结果可以看出,Kotlin-serialisation 花费了 12.11 秒,Moshi 花费了 11.96 秒,而 Gson 花费了 13.31 秒。

测试用例 2 — 字段不存在

在这里,我从 US 节点中移除了 name 节点,如下截图所示。

图片

Kotlin-Serialisation测试截图如下

图片

Moshi测试截图如下

图片

在这种情况下,Gson 忽略了该字段并完全执行了。

对于所有这些,我们可以看到 Moshi 的错误相对于其他两者来说更具体。

测试用例 3 – 使用基准报告

单次迭代结果

图片

5次迭代结果

图片

结论

总体而言,在序列化/反序列化方面,Moshi 显示出了良好的结果,但 Kotlin 序列化具有 Protobuf 支持,可以帮助降低延迟和有效载荷大小,因此根据用途,人们可以谨慎选择所需的库。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/246916.html

联系我们
联系我们
分享本页
返回顶部