perf: EndProcFast — eliminate defer recover() from RTL hot paths
Problem: every RTL function calls defer t.EndProc() which does recover(). 50K SEEK loop = 250K recover() calls = ~12ms wasted. Solution: EndProcFast() skips recover (only needs endFrame restore). Applied to ALL RTL functions in strings.go, rdd.go, missing.go, database.go. EndProc() with recover kept for generated PRG code (needs BEGIN SEQUENCE). Analysis (50K sequential SEEK breakdown): Go NTX Seek direct: 7ms (faster than Harbour 27ms!) PRG VM overhead: 38ms (Frame + RTL calls + key generation) Key generation: 25ms (Str+LTrim+PadL+PadR = 5 RTL Frame/EndProc per iter) With EndProcFast: RTL overhead reduced ~30%. CDX SCOPE: 2ms (Harbour 4ms — 2x FASTER!) 82/82 stress PASS. 14 packages ALL PASS. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -250,12 +250,21 @@ func (t *Thread) EndProc() {
|
||||
if hbErr, ok := r.(*HbError); ok {
|
||||
t.handleSequenceError(hbErr)
|
||||
} else {
|
||||
// Print error to stderr before re-panic
|
||||
fmt.Fprintf(os.Stderr, "Five runtime error: %v\n", r)
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
t.endFrame()
|
||||
}
|
||||
|
||||
// EndProcFast is called by RTL functions that don't need recover().
|
||||
// ~3x faster than EndProc (no defer recover overhead).
|
||||
func (t *Thread) EndProcFast() {
|
||||
t.endFrame()
|
||||
}
|
||||
|
||||
// endFrame restores the previous call frame.
|
||||
func (t *Thread) endFrame() {
|
||||
if t.callSP > 0 {
|
||||
t.callSP--
|
||||
if t.callSP > 0 {
|
||||
|
||||
Reference in New Issue
Block a user