关于json:XJSON-是如何实现四则运算的

34次阅读

共计 1743 个字符,预计需要花费 5 分钟才能阅读完成。

前言

在上一篇中介绍了 xjson 的性能个性以及应用查问语法疾速不便的获取 JSON 中的值。

同时这次也更新了一个版本,次要是两个降级:

  1. 对转义字符的反对。
  2. 性能优化,大概晋升了 30%⬆️。

转义字符

先说第一个转义字符,不论是原始 JSON 字符串中存在转义字符,还是查问语法中存在转义字符都曾经反对,具体用法如下:

    str = `{"1a.b.[]":"b"}`
    get = Get(str, "1a\\.b\\.\\[\\]")
    assert.Equal(t, get.String(), "b")

    str = `{".":"b"}`
    get = Get(str, "\\.")
    assert.Equal(t, get.String(), "b")

    str = `{"a":"{\"a\":\"123\"}"}`
    get = Get(str, "a")
    fmt.Println(get)
    assert.Equal(t, get.String(), "{\"a\":\"123\"}")
    assert.Equal(t, Get(get.String(), "a").String(), "123")

    str = `{"a":"{\"a\":[1,2]}"}`
    get = Get(str, "a")
    fmt.Println(get)
    assert.Equal(t, get.String(), "{\"a\":[1,2]}")
    assert.Equal(t, Get(get.String(), "a[0]").Int(), 1)

性能优化

性能也有局部优化,大概比上一版本晋升了 30%。

pkg: github.com/crossoverJie/xjson/benckmark
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkDecode-12               14968         77130 ns/op       44959 B/op        1546 allocs/op
PASS

------------------------------------
pkg: github.com/crossoverJie/xjson/benckmark
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkDecode-12               19136         62960 ns/op       41593 B/op        1407 allocs/op
PASS

但总体来说还有不少优化空间,次要是下限毕竟低,和官网库比还是有不小的差距。

实现四则运算

接下来聊聊四则运算是如何实现的,这自身算是一个比拟有意思的 feature,尽管用的场景不多🙂。

先来看看是如何应用的:

    json :=`{"alice":{"age":10},"bob":{"age":20},"tom":{"age":20}}`
    query := "(alice.age+bob.age) * tom.age"
    arithmetic := GetWithArithmetic(json, query)
    assert.Equal(t, arithmetic.Int(), 600)

输出一个 JSON 字符串以及计算公式而后失去计算结果。

其实实现原理也比较简单,总共分为是三步:

  1. json 进行词法剖析,失去一个四则运算的第一步 token
  2. 基于该 token 流,生产出最终的四则运算表达式,比方 (3+2)*5
  3. 调用四则运算处理器,拿到最终后果。

先看第一步,依据 (alice.age+bob.age) * tom.age 解析出 token

第二步,解析该 token,碰到 Identifier 类型时,将其解析为具体的数据。

而其余类型的 token 间接拼接字符串即可,最终生成表达式:(10+20)*20

这一步的外围性能是由 xjson.Get(json, query) 函数提供的。

要害代码如下图所示:

最终的目标就是可能生成一个表达式,只有拿到这个四则运算表达式便能失去最终计算结果。

而最终的计算逻辑其实也挺简略,构建一个 AST 树,而后深度遍历递归求解即可,如下图所示:

这一步的外围性能是有之前实现的脚本解释器 gscipt 提供的。

感兴趣的敌人能够查看源码。

总结

一个 JSON 库的性能其实并不多,欢送大家分享平时用 JSON 库的罕用性能;也欢送大家体验下这个库。

源码地址:
https://github.com/crossoverJie/xjson

正文完
 0