심지어 성능을 크게 향상 enablePackrat
을, 사용 후 원하는 것보다 infixNotation
의 내 구현이 느리게 실행됩니다.대한 파싱의 infixNotation 최적화
구문 분석 인식하고 문자열의 다음과 같은 유형의 구문 분석에 필요한 :
- 기본 산술 연산, 숫자, 부정, 그리고 괄호 형식으로
- 그룹화 함수 호출과 같이
prefix::dotted.alphanum.string -> [prefix::dotted.alphanum.string]
- 문자열을 그룹 예
pow(some::var + 2.3, 5) -> [pow, [[some::var, +, 2.3], 5]]
내가 사용하고 코드 :
def parse_expression(expr_str):
fraction = Combine("." + Word(nums))
number = Combine(Word(nums) + Optional(fraction)).setParseAction(str_to_num)
event_id_expr = Word(alphanums + "_") + "::"
dotted_columns = Combine(Word(alphanums + "_") + Optional("."))
column_expr = Combine(event_id_expr + OneOrMore(dotted_columns))
arith_expr = infixNotation(column_expr | number, [
(Word(alphanums + "_"), 1, opAssoc.RIGHT),
("-", 1, opAssoc.RIGHT),
(oneOf("* /"), 2, opAssoc.LEFT),
(oneOf("+ -"), 2, opAssoc.LEFT),
(Literal(","), 2, opAssoc.LEFT)
])
parsed_expr = arith_expr.parseString(expr_str).asList()[0]
return parsed_expr
def str_to_num(t):
num_str = t[0]
try:
return int(num_str)
except ValueError:
return float(num_str)
내가 그 실질적인 성능 향상을 초래 할 수 있습니다 어떤 변화가 있습니까? 구문 분석하는 구조는 매우 간단하지만 일괄 처리됩니다. 평균적으로 각 문자열은 ~ 5.3ms를 사용합니다. 나는 또한 당신의 식별자의 대부분을 수정
def parse_expression(expr_str):
number = pyparsing_common.number()
event_id_expr = Word(alphas+"_", alphanums + "_") + "::"
dotted_columns = Combine(Word(alphas+"_", alphanums + "_") + Optional("."))
column_expr = Combine(event_id_expr + OneOrMore(dotted_columns))
func_name = Word(alphas+"_", alphanums+'_')
LPAR, RPAR = map(Suppress, "()")
arith_expr = Forward()
func_call = Group(func_name('name')
+ LPAR
+ Group(Optional(delimitedList(arith_expr)))("args")
+ RPAR)
arith_expr <<= infixNotation(number | func_call | column_expr, [
("-", 1, opAssoc.RIGHT),
(oneOf("* /"), 2, opAssoc.LEFT),
(oneOf("+ -"), 2, opAssoc.LEFT),
])
parsed_expr = arith_expr.parseString(expr_str)[0]
return parsed_expr
: 그들은 운영자가, 당신이 이동 기능은 infixNotation
에 대한 피연산자 식으로 호출하는 것이 더 낫다 생각하는 것처럼 당신이 "fudging"기능이있는 것처럼
'number'를'pyparsing_common.number'로 대체하십시오. 그것은 당신의'str_to_num' 구문 분석 액션처럼 int 나 float로 변환 될 것입니다. 그러나 더 중요한 것은, 하나의 Regex를 사용하여 Combine으로 싸여진 더 작은 표현식 대신에 구문 분석을하는 것입니다. 나는이 간단한 변화가 측정 가능한 성능 차이를 만들 수 있음을 발견했다. – PaulMcG
좋습니다. 그 혼자서 ~ .5ms를 깎아 내었습니다. – user3747260
한계에 다다 렸을 수 있습니다. - 깎아 지른듯한 미덕은 런타임 속도가 아닙니다. – PaulMcG