美文网首页
Python学习:jsonpath的性能问题

Python学习:jsonpath的性能问题

作者: khaos | 来源:发表于2020-12-26 23:21 被阅读0次

问题

前面刚总结了,利用jsonpath可以快速访问和设置json对象节点值的帖子。没想到这么快就打脸了。python的jsonpath居然性能如此之差,简直无法接受。

今天其实就是抛一个问题,作为记录,希望后续能够找到解决之道。

方案

利用python装饰器,可以轻松写一个记录函数执行时间的功能。代码如下:

import time
from functools import wraps


def exec_time():
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            beg = time.time() * 1000
            ret = func(*args, **kwargs)
            end = time.time() * 1000
            print('func:{%s} exec time is:{%.5f} ms' % (func.__name__, end - beg))
            return ret

        return wrapper

    return decorator

回到jsonpath问题上来,简单写了一个设置节点值的代码,如下:

js = {'a': 10, 'b': 20, 'c': {'e': 10, 'f': 'string'}, 'c1': {'e': 10, 'f': 'string'}, 'c2': {'e': 10, 'f': 'string'}}
JsonHelper(js).set('e', 20)
JsonHelper(js).get('e')
JsonHelper(js).set('e', 30)
JsonHelper(js).get('e')
JsonHelper(js).set('e', 40)
JsonHelper(js).get('e')
JsonHelper(js).set('e', 50)
JsonHelper(js).get('e')

输出为:

func:{set} exec time is:{9.77808} ms
func:{get} exec time is:{7.33887} ms
func:{set} exec time is:{6.12109} ms
func:{get} exec time is:{6.15625} ms
func:{set} exec time is:{5.82568} ms
func:{get} exec time is:{5.17139} ms
func:{set} exec time is:{4.96606} ms
func:{get} exec time is:{4.96899} ms

这么简单的json节点set和get,居然要接近10ms级别。再对比python对象的直接访问:

@exec_time()
def op_dict(data, field):
    data[field] = 20
    return data

输出:

func:{op_dict} exec time is:{0.00122} ms

python直接访问,性能居然相差千遍以上。jsonpath-ng的性能确实很差,库的实现有问题。不死心,又找到另外两个jsonpath库,一个就是jsonpath,一个是jsonpath-rw,再次验证性能:

import jsonpath
@exec_time()
def test_jsonpath(data, field):
    return jsonpath.jsonpath(data, field)

from jsonpath_rw import parse as parserw
@exec_time()
def test_jsonpathrw(data, field):
    jsonpath_expr = parserw(field)
    return jsonpath_expr.find(data)

js = {'a': 10, 'b': 20, 'c': {'e': 10, 'f': 'string'}, 'c1': {'e': 10, 'f': 'string'}, 'c2': {'e': 10, 'f': 'string'}}
print(test_jsonpath(js, '$..e'))
print(test_jsonpathrw(js, '$..e'))

输出为:

func:{test_jsonpath} exec time is:{0.57471} ms
func:{test_jsonpathrw} exec time is:{5.48584} ms

结果很明显,jsonpath比jsonpath-ng性能相差10倍,但也并不算很好,与原始的json对象直接访问近100倍性能之差。jsonpath-rw的性能和jsonpath-ng差不多,实际上jsonpath-ng就是基于jsonpath-rw改造的。可惜jsonpath还不支持节点设置功能,jsonpath也不是好的选择。

讨论

本文中的exec_time装饰器,可以作为日常开发调测的工具箱中,尤其是引用第三方库的时候,需要及时验证下性能问题。

对于jsonpath,目前第三方库中确实难以找到合适的库可以使用。期待库的作者能够意识到性能问题并修复。后面的方向,找一下c语言的jsonpath库,试一试集成到python中,规避性能问题。

相关文章

网友评论

      本文标题:Python学习:jsonpath的性能问题

      本文链接:https://www.haomeiwen.com/subject/jdennktx.html