From 8f9f86ea433f211114f5a7e5d01b480ee8b1d7bb Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Mon, 30 Mar 2026 12:48:09 +0900 Subject: [PATCH] Eliminate unnecessary bounds checks in hot paths - Replace len(args[start:start+na]) > 0 with na > 0 to avoid slice bounds check - Use range loops instead of manual index loops for cols/decltype slices - Use range variable v.Ordinal instead of re-indexing args[i].Ordinal - Add bounds hint for decltype access in nextSyncLocked loop --- sqlite3.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sqlite3.go b/sqlite3.go index dffc2bd..76b0f23 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -875,7 +875,7 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []driver.Named // consume the number of arguments used in the current // statement and append all named arguments not // contained therein - if len(args[start:start+na]) > 0 { + if na > 0 { stmtArgs = append(stmtArgs, args[start:start+na]...) for i := range args { if (i < start || i >= na) && args[i].Name != "" { @@ -1968,7 +1968,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error { bindIndices := make([][3]int, len(args)) prefixes := []string{":", "@", "$"} for i, v := range args { - bindIndices[i][0] = args[i].Ordinal + bindIndices[i][0] = v.Ordinal if v.Name != "" { for j := range prefixes { cname := C.CString(prefixes[j] + v.Name) @@ -2179,7 +2179,7 @@ func (rc *SQLiteRows) Columns() []string { defer rc.s.mu.Unlock() if rc.s.s != nil && int(rc.nc) != len(rc.cols) { rc.cols = make([]string, rc.nc) - for i := 0; i < int(rc.nc); i++ { + for i := range rc.cols { rc.cols[i] = C.GoString(C.sqlite3_column_name(rc.s.s, C.int(i))) } } @@ -2189,7 +2189,7 @@ func (rc *SQLiteRows) Columns() []string { func (rc *SQLiteRows) declTypes() []string { if rc.s.s != nil && rc.decltype == nil { rc.decltype = make([]string, rc.nc) - for i := 0; i < int(rc.nc); i++ { + for i := range rc.decltype { rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) } } @@ -2251,11 +2251,13 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error { rc.declTypes() + decltype := rc.decltype + _ = decltype[len(dest)-1] for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) - switch rc.decltype[i] { + switch decltype[i] { case columnTimestamp, columnDatetime, columnDate: var t time.Time // Assume a millisecond unix timestamp if it's 13 digits -- too @@ -2295,7 +2297,7 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error { n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i))) s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n)) - switch rc.decltype[i] { + switch decltype[i] { case columnTimestamp, columnDatetime, columnDate: var t time.Time s = strings.TrimSuffix(s, "Z")