Cerberus/regex瓶颈性能验证实践

2024-05-13 13:25:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我在用AIOHTTP做一个网络应用。我正在使用Cerberus验证用户输入。我使用wrk基准测试工具运行了一些测试,发现以下Cerberus验证器:

"uri": {
        "type": "string",
        "coerce": str,
        "required": True,
        "minlength": 1,
        "maxlength": 255,
        "regex": "^[a-zA-Z0-9/_]+$"
    }

为网页添加约10-15%的加载时间。这是我无法接受的。如何处理这个问题?只是正则表达式引擎吗?是否有已知速度更快的模块?我知道字符串解析函数通常比正则表达式快。有没有不使用正则表达式的验证引擎?一个将正则表达式转换为字符串解析的工具会很有趣

编辑:我运行了一个探查器:

from cerberus import Validator
from speed_profiler import SpeedProfiler
from pprint import pprint

def referer_validator(value):
    if len(value) < 1 or len(value) > 256:
        return False
    if not any(not l.isalnum() and l not in ['_', '/'] for l in value):
        return False
    return True


v = Validator()
v.schema = {
    "path": {
        "type": "string",
        "coerce": str,
        "required": True,
        "minlength": 1,
        "maxlength": 255,
        "regex": "^[a-zA-Z0-9/_]+$"
    }
}

sp = SpeedProfiler('Cerberus')

v.validate({'path': '/some/path_foo'})

sp.mark('Parser Function')

referer_validator('/some/path_foo')

profile = sp.stop()
pprint(profile)

这证实了Cerberus的速度很慢:

[{'duration': 0.00029901403468102217,
  'identifier': 'Cerberus',
  'line_num': 27,
  'percent_time': 98.26},
 {'duration': 5.29497629031539e-06,
  'identifier': 'Parser Function',
  'line_num': 31,
  'percent_time': 1.74}]

这证实了Cerberus的速度很慢。现在,为了提高速度,我使用这个:

def path_valid(value):
    if len(value) < 1 or len(value) > 256:
        return False
    if not any(not l.isalnum() and l not in ['_', '/'] for l in value):
        return False
    return True

Tags: pathinfromimportfalsetruelenreturn
1条回答
网友
1楼 · 发布于 2024-05-13 13:25:37

如果您喜欢使用非正则表达式解决方案,可以使用

def path_valid(value):
    if len(value) < 1 or len(value) > 255:
        return False
    if not any(not l.isalnum() and l not in ['_', '/'] for l in value):
        return False
    return True

如果值的长度小于1或大于255(由于if len(value) < 1 or len(value) > 255检查),则此方法无法通过验证,如果存在非字母数字的字符且不是_/(使用if not any(not l.isalnum() and l not in ['_', '/'] for l in value)完成检查),则将发生失败

见a Python test here

相关问题 更多 >