首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >get_json_object与from_json的性能

get_json_object与from_json的性能
EN

Stack Overflow用户
提问于 2020-09-03 19:27:53
回答 2查看 1.5K关注 0票数 1

我很好奇星火如何使用get_json_object方法,以及我是否正确地使用了它。假设我有一个string类型的列data (JSON编码的),每一行的值都相当大(~1MB)。

如果我想检索和处理参数的子集,我可以很容易地做到:

代码语言:javascript
运行
复制
param_a = get_json_object("data", "$.my.param.a").cast("int")
param_b = get_json_object("data", "$.my.param.b").cast("int")

my_sum = param_a + param_b

星火会自动派生出它只需要在内部解码一次JSON,然后再使用该状态,还是它会对get_json_object的每个调用进行解码?

另外,我也可以使用from_json并在定义良好的模式中检索:

代码语言:javascript
运行
复制
_schema = StructType().add("a", IntegerType()).add("b", IntegerType())
params = from_json(get_json_object("data", "$.my.param"), _schema)

my_sum = params["a"] + params["b"]

因此,我的问题是:这些方法在性能上是否具有可比性,和/或是否有其他原因可以使用一种方法而另一种方法呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-04 09:34:12

我对Apache这一部分的理解是相当有限的,但我想分享一下get_json_object的代码,这些代码可以提供更多的信息(并且可能会给出一个非常有用的答案)。

tl;dr:我建议在访问多个JSON字段时使用from_json(get_json_object(...), ...),以避免更昂贵的get_json_object(内存方面)。

(我在使用Scala,但这并不重要,只是它更接近“裸金属”)

代码语言:javascript
运行
复制
// let's use a very simple query to demo the concept
val q = sql("""SELECT get_json_object('{"a":"b"}', '$.a'), get_json_object('{"aa":"bb"}', '$.aa')""")
scala> q.explain
== Physical Plan ==
*(1) Project [b AS get_json_object({"a":"b"}, $.a)#10, bb AS get_json_object({"aa":"bb"}, $.aa)#11]
+- *(1) Scan OneRowRelation[]

正如您可能已经注意到的,物理查询计划使用两个不同的get_json_object表达式(一个使用#10,另一个使用#11唯一标识符)。

get_json_object只是掩护下的GetJsonObject催化剂表达式,而评估方法则是所有魔术发生的地方。

在某种程度上,evalCreateJacksonParser.utf8String(jsonFactory, jsonStr)。它使用这个jsonFactory值,由于它是val对象SharedFactory的一部分,所以它恰好在任何Java/Python/JVM代码之间共享。在Scala中,关键字object在星火执行器(单个JVM)上的所有任务中提供一个实例。这当然是共享实例,但这只是一个工厂(而不是JSON解析器本身)。

我的理解是,每次请求一个新的JSON解析器时,都会创建一个新的解析器(可能是因为它是一个可变的“猛兽”?)。你必须查阅杰克逊的JsonFactoryBuilder才能找到答案。

票数 2
EN

Stack Overflow用户

发布于 2020-09-04 05:56:54

所以我写了一个测试(GitHub上的要点)来测试它。基本上,通过以下变量执行我前面描述的设置:

  • 要解码的参数数
  • 行数
  • 每个数据行的大小
  • 平均超过的复制/实验次数

使用具有1KB数据JSON编码的字符串内容(和500个副本)的100行的8个参数,结果如下:

代码语言:javascript
运行
复制
{<function _method_b at 0x7fb73d30e200>: 0.16155768394470216,
 <function _method_a at 0x7fb73d30e320>: 0.22132105827331544}

因此,在这种情况下,在执行大约25%的模式方面有了改进。

此外:

  • 将参数的数量从8减少到2,实际上浪费了差异:
代码语言:javascript
运行
复制
{<function _method_b at 0x7f43d7dc4200>: 0.15471874809265138,
 <function _method_a at 0x7f43d7dc4320>: 0.14935027599334716}

因此:我的结论是,如果您想要解释一个结构的许多参数,那么强制模式的性能就会有所提高,但是如果只是少数几个参数,那么只使用get_json_object和强制转换就可以达到同样的性能(而且更容易读/写)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63730434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档