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
This commit is contained in:
14
sqlite3.go
14
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
|
// consume the number of arguments used in the current
|
||||||
// statement and append all named arguments not
|
// statement and append all named arguments not
|
||||||
// contained therein
|
// contained therein
|
||||||
if len(args[start:start+na]) > 0 {
|
if na > 0 {
|
||||||
stmtArgs = append(stmtArgs, args[start:start+na]...)
|
stmtArgs = append(stmtArgs, args[start:start+na]...)
|
||||||
for i := range args {
|
for i := range args {
|
||||||
if (i < start || i >= na) && args[i].Name != "" {
|
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))
|
bindIndices := make([][3]int, len(args))
|
||||||
prefixes := []string{":", "@", "$"}
|
prefixes := []string{":", "@", "$"}
|
||||||
for i, v := range args {
|
for i, v := range args {
|
||||||
bindIndices[i][0] = args[i].Ordinal
|
bindIndices[i][0] = v.Ordinal
|
||||||
if v.Name != "" {
|
if v.Name != "" {
|
||||||
for j := range prefixes {
|
for j := range prefixes {
|
||||||
cname := C.CString(prefixes[j] + v.Name)
|
cname := C.CString(prefixes[j] + v.Name)
|
||||||
@@ -2179,7 +2179,7 @@ func (rc *SQLiteRows) Columns() []string {
|
|||||||
defer rc.s.mu.Unlock()
|
defer rc.s.mu.Unlock()
|
||||||
if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
|
if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
|
||||||
rc.cols = make([]string, rc.nc)
|
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)))
|
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 {
|
func (rc *SQLiteRows) declTypes() []string {
|
||||||
if rc.s.s != nil && rc.decltype == nil {
|
if rc.s.s != nil && rc.decltype == nil {
|
||||||
rc.decltype = make([]string, rc.nc)
|
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))))
|
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()
|
rc.declTypes()
|
||||||
|
|
||||||
|
decltype := rc.decltype
|
||||||
|
_ = decltype[len(dest)-1]
|
||||||
for i := range dest {
|
for i := range dest {
|
||||||
switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
|
switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
|
||||||
case C.SQLITE_INTEGER:
|
case C.SQLITE_INTEGER:
|
||||||
val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
|
val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
|
||||||
switch rc.decltype[i] {
|
switch decltype[i] {
|
||||||
case columnTimestamp, columnDatetime, columnDate:
|
case columnTimestamp, columnDatetime, columnDate:
|
||||||
var t time.Time
|
var t time.Time
|
||||||
// Assume a millisecond unix timestamp if it's 13 digits -- too
|
// 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)))
|
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))
|
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:
|
case columnTimestamp, columnDatetime, columnDate:
|
||||||
var t time.Time
|
var t time.Time
|
||||||
s = strings.TrimSuffix(s, "Z")
|
s = strings.TrimSuffix(s, "Z")
|
||||||
|
|||||||
Reference in New Issue
Block a user