From b0c414a3426c26d98df4f205f3707397eb5671e9 Mon Sep 17 00:00:00 2001 From: Piotr Jastrzebski Date: Thu, 18 Jul 2024 13:26:42 +0200 Subject: [PATCH 1/2] Optimize arguments handling Remove memory/cpu overhead of handling arguments when they are empty. This is important in case of user loading a dump of their database. In such a case, there are no arguments at all and the number of statements is usually big. When testing on a 650M sql file this change reduces number of total allocation from 122772583kB to 38511376 so ~69%. Signed-off-by: Piotr Jastrzebski --- libsql/internal/hrana/stream_request.go | 15 ++++++++++----- libsql/internal/http/hranaV2/hranaV2.go | 6 +++++- libsql/internal/http/shared/statement.go | 7 +++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/libsql/internal/hrana/stream_request.go b/libsql/internal/hrana/stream_request.go index 0b00dc4..a47b077 100644 --- a/libsql/internal/hrana/stream_request.go +++ b/libsql/internal/hrana/stream_request.go @@ -16,13 +16,15 @@ func CloseStream() StreamRequest { return StreamRequest{Type: "close"} } -func ExecuteStream(sql string, params shared.Params, wantRows bool) (*StreamRequest, error) { +func ExecuteStream(sql string, params *shared.Params, wantRows bool) (*StreamRequest, error) { stmt := &Stmt{ Sql: &sql, WantRows: wantRows, } - if err := stmt.AddArgs(params); err != nil { - return nil, err + if params != nil { + if err := stmt.AddArgs(*params); err != nil { + return nil, err + } } return &StreamRequest{Type: "execute", Stmt: stmt}, nil } @@ -40,14 +42,17 @@ func ExecuteStoredStream(sqlId int32, params shared.Params, wantRows bool) (*Str func BatchStream(sqls []string, params []shared.Params, wantRows bool, transactional bool) (*StreamRequest, error) { batch := &Batch{} + addArgs := len(params) > 0 for idx, sql := range sqls { s := sql stmt := &Stmt{ Sql: &s, WantRows: wantRows, } - if err := stmt.AddArgs(params[idx]); err != nil { - return nil, err + if addArgs { + if err := stmt.AddArgs(params[idx]); err != nil { + return nil, err + } } var condition *BatchCondition if transactional { diff --git a/libsql/internal/http/hranaV2/hranaV2.go b/libsql/internal/http/hranaV2/hranaV2.go index 1ce4831..6c79014 100644 --- a/libsql/internal/http/hranaV2/hranaV2.go +++ b/libsql/internal/http/hranaV2/hranaV2.go @@ -293,7 +293,11 @@ func (h *hranaV2Conn) executeStmt(ctx context.Context, query string, args []driv } msg := &hrana.PipelineRequest{} if len(stmts) == 1 { - executeStream, err := hrana.ExecuteStream(stmts[0], params[0], wantRows) + var p *shared.Params + if len(params) > 0 { + p = ¶ms[0] + } + executeStream, err := hrana.ExecuteStream(stmts[0], p, wantRows) if err != nil { return nil, fmt.Errorf("failed to execute SQL: %s\n%w", query, err) } diff --git a/libsql/internal/http/shared/statement.go b/libsql/internal/http/shared/statement.go index ce44055..584a5fc 100644 --- a/libsql/internal/http/shared/statement.go +++ b/libsql/internal/http/shared/statement.go @@ -32,13 +32,16 @@ func ParseStatement(sql string) ([]string, []ParamsInfo, error) { } func ParseStatementAndArgs(sql string, args []driver.NamedValue) ([]string, []Params, error) { + stmts, _ := sqliteparserutils.SplitStatement(sql) + + if len(args) == 0 { + return stmts, nil, nil + } parameters, err := ConvertArgs(args) if err != nil { return nil, nil, err } - stmts, _ := sqliteparserutils.SplitStatement(sql) - stmtsParams := make([]Params, len(stmts)) totalParametersAlreadyUsed := 0 for idx, stmt := range stmts { From bd6bb5bee66c13a3715d5be6d606abefb1284123 Mon Sep 17 00:00:00 2001 From: Piotr Jastrzebski Date: Thu, 18 Jul 2024 14:00:54 +0200 Subject: [PATCH 2/2] Reserve enough space when creating batch This reduces number of allocations during batch creation from 5636431kB to 1679694kB which is ~70%. Signed-off-by: Piotr Jastrzebski --- libsql/internal/hrana/stream_request.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libsql/internal/hrana/stream_request.go b/libsql/internal/hrana/stream_request.go index a47b077..caea86b 100644 --- a/libsql/internal/hrana/stream_request.go +++ b/libsql/internal/hrana/stream_request.go @@ -41,7 +41,11 @@ func ExecuteStoredStream(sqlId int32, params shared.Params, wantRows bool) (*Str } func BatchStream(sqls []string, params []shared.Params, wantRows bool, transactional bool) (*StreamRequest, error) { - batch := &Batch{} + size := len(sqls) + if transactional { + size += 1 + } + batch := &Batch{Steps: make([]BatchStep, 0, size)} addArgs := len(params) > 0 for idx, sql := range sqls { s := sql