if(not(isPresent($calculated_FirstAccessUserHash))){1}else{if($ForcedRelativeSuspiciousValue1){1}else{if($ForcedRelativeSuspiciousValue5){5}else{if($default_RelativeSuspiciousValue==5){5}else{if(($POST_PROCESS_OriginalSpec_CountryIsNotJapan>0.0)|($POST_PROCESS_OriginalSpec_BlackListOnOtherSites>0.0)|($POST_PROCESS_OriginalSpec_SuspiciousProvider>0.0)|($POST_PROCESS_OriginalSpec_OneUserAccessToMultiAccount>0.0)){5}else{$default_RelativeSuspiciousValue}}}}}
背景
unlaxer-parser #40(packrat メモ化, 3.0.10)+
-Dtinyexpression.p4.memoize=trueで、#19 の fraud 検知式のうち boolean/括弧曖昧形(#19 例1–4)は <0.5s に指数崩壊した。だが 深いネスト if 形(#19 例5)は memoize ON でも 12–30s と「数秒」に届かない。production では従来通り parse deadline(10s)→legacy fallback で安全に処理されるが、P4 経路に載せるには本式の根治が必要。対象式(#5、
CalculatorImplTest.testCompilationFailedFunctions/P4PackratFraudFormulaTest):これまでに除外済みの仮説(推測×3 すべて律速ではない)
(rule,position)の再導出 —PackratMemoTable.isSuccessMemoizableを全許可にした diagnostic(成功メモ化を全ルールに適用)でも P4 LSP: go-to-definition / find-references (ScopeStore 活用) #5 は ~12s 止まり。再パースは律速でない。@backref除外 — 上記 diagnostic でVariableRef(@backref) 含む部分木も成功メモ化したが効果なし。StringSource.peek二重割当 — de-dup(unlaxer-parser PR feat(p4): packrat memoization ON by default — parity corpus fallback 3→0 #51, merged)しても P4 LSP: go-to-definition / find-references (ScopeStore 活用) #5 不変(むしろ計測 29s のことも)。症状のシグネチャ → GC / アロケーション律速
parse 時間が 12s〜30s と実行ごとに大きくばらつく(同一入力・同一コード)。これは CPU 律速ではなく ヒープ/GC 圧(大量の短命オブジェクト割当) の典型。
調査方針(推測をやめ、実測する)
tinyexpression.p4.parse.timeout.millis=0)の 割当フレーム上位と CPU 上位を取る。-verbose:gcで GC 回数/停止時間も。StringSource.subSource/subString: 毎回new String(codePoints,...)+source.codePoints().toArray()で O(length) コピー。深いネストで peek/subSource が O(n) 回 × O(n) コピー = O(n²) の疑い。→ 根治は codePoints 配列を親と共有し [start,len) 窓で参照(コピー廃止)。大きめの core 改修。ParseContext.trackCursorProgress/parseFramespush/pop /startParse/endParse: parser 呼び出し毎の割当・処理。farthestFailure*/trialHistory/maxReachedStackElementsの毎回更新・リスト割当。System.nanoTime()毎回(CPU 小だが頻度大)。(parser, consumed, matched, tokenKind, invertMatch)で matched が毎回変わるとなると同一 consumed でもキャッシュミス → 実質メモ無効の可能性。P4 LSP: go-to-definition / find-references (ScopeStore 活用) #5 で memo ヒット率を計測(デバッグカウンタ)。受入条件
P4PackratFraudFormulaTestの P4 LSP: go-to-definition / find-references (ScopeStore 活用) #5 を <5s 厳格 assert に戻す)。unlaxer-commonフルスイート緑・default(memoize OFF) 挙動不変。関連
p4-issue40-packrat(除外済み仮説・diagnostic 結果を記録)。P4PackratFraudFormulaTest。