1 package pgconn_test
2
3 import (
4 "bytes"
5 "context"
6 "os"
7 "testing"
8
9 "github.com/jackc/pgx/v5/pgconn"
10 "github.com/stretchr/testify/require"
11 )
12
13 func BenchmarkConnect(b *testing.B) {
14 benchmarks := []struct {
15 name string
16 env string
17 }{
18 {"Unix socket", "PGX_TEST_UNIX_SOCKET_CONN_STRING"},
19 {"TCP", "PGX_TEST_TCP_CONN_STRING"},
20 }
21
22 for _, bm := range benchmarks {
23 bm := bm
24 b.Run(bm.name, func(b *testing.B) {
25 connString := os.Getenv(bm.env)
26 if connString == "" {
27 b.Skipf("Skipping due to missing environment variable %v", bm.env)
28 }
29
30 for i := 0; i < b.N; i++ {
31 conn, err := pgconn.Connect(context.Background(), connString)
32 require.Nil(b, err)
33
34 err = conn.Close(context.Background())
35 require.Nil(b, err)
36 }
37 })
38 }
39 }
40
41 func BenchmarkExec(b *testing.B) {
42 expectedValues := [][]byte{[]byte("hello"), []byte("42"), []byte("2019-01-01")}
43 benchmarks := []struct {
44 name string
45 ctx context.Context
46 }{
47
48
49 {"background context", context.Background()},
50 {"empty context", context.TODO()},
51 }
52
53 for _, bm := range benchmarks {
54 bm := bm
55 b.Run(bm.name, func(b *testing.B) {
56 conn, err := pgconn.Connect(bm.ctx, os.Getenv("PGX_TEST_DATABASE"))
57 require.Nil(b, err)
58 defer closeConn(b, conn)
59
60 b.ResetTimer()
61
62 for i := 0; i < b.N; i++ {
63 mrr := conn.Exec(bm.ctx, "select 'hello'::text as a, 42::int4 as b, '2019-01-01'::date")
64
65 for mrr.NextResult() {
66 rr := mrr.ResultReader()
67
68 rowCount := 0
69 for rr.NextRow() {
70 rowCount++
71 if len(rr.Values()) != len(expectedValues) {
72 b.Fatalf("unexpected number of values: %d", len(rr.Values()))
73 }
74 for i := range rr.Values() {
75 if !bytes.Equal(rr.Values()[i], expectedValues[i]) {
76 b.Fatalf("unexpected values: %s %s", rr.Values()[i], expectedValues[i])
77 }
78 }
79 }
80 _, err = rr.Close()
81
82 if err != nil {
83 b.Fatal(err)
84 }
85 if rowCount != 1 {
86 b.Fatalf("unexpected rowCount: %d", rowCount)
87 }
88 }
89
90 err := mrr.Close()
91 if err != nil {
92 b.Fatal(err)
93 }
94 }
95 })
96 }
97 }
98
99 func BenchmarkExecPossibleToCancel(b *testing.B) {
100 conn, err := pgconn.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE"))
101 require.Nil(b, err)
102 defer closeConn(b, conn)
103
104 expectedValues := [][]byte{[]byte("hello"), []byte("42"), []byte("2019-01-01")}
105
106 b.ResetTimer()
107
108 ctx, cancel := context.WithCancel(context.Background())
109 defer cancel()
110
111 for i := 0; i < b.N; i++ {
112 mrr := conn.Exec(ctx, "select 'hello'::text as a, 42::int4 as b, '2019-01-01'::date")
113
114 for mrr.NextResult() {
115 rr := mrr.ResultReader()
116
117 rowCount := 0
118 for rr.NextRow() {
119 rowCount++
120 if len(rr.Values()) != len(expectedValues) {
121 b.Fatalf("unexpected number of values: %d", len(rr.Values()))
122 }
123 for i := range rr.Values() {
124 if !bytes.Equal(rr.Values()[i], expectedValues[i]) {
125 b.Fatalf("unexpected values: %s %s", rr.Values()[i], expectedValues[i])
126 }
127 }
128 }
129 _, err = rr.Close()
130
131 if err != nil {
132 b.Fatal(err)
133 }
134 if rowCount != 1 {
135 b.Fatalf("unexpected rowCount: %d", rowCount)
136 }
137 }
138
139 err := mrr.Close()
140 if err != nil {
141 b.Fatal(err)
142 }
143 }
144 }
145
146 func BenchmarkExecPrepared(b *testing.B) {
147 expectedValues := [][]byte{[]byte("hello"), []byte("42"), []byte("2019-01-01")}
148
149 benchmarks := []struct {
150 name string
151 ctx context.Context
152 }{
153
154
155 {"background context", context.Background()},
156 {"empty context", context.TODO()},
157 }
158
159 for _, bm := range benchmarks {
160 bm := bm
161 b.Run(bm.name, func(b *testing.B) {
162 conn, err := pgconn.Connect(bm.ctx, os.Getenv("PGX_TEST_DATABASE"))
163 require.Nil(b, err)
164 defer closeConn(b, conn)
165
166 _, err = conn.Prepare(bm.ctx, "ps1", "select 'hello'::text as a, 42::int4 as b, '2019-01-01'::date", nil)
167 require.Nil(b, err)
168
169 b.ResetTimer()
170
171 for i := 0; i < b.N; i++ {
172 rr := conn.ExecPrepared(bm.ctx, "ps1", nil, nil, nil)
173
174 rowCount := 0
175 for rr.NextRow() {
176 rowCount++
177 if len(rr.Values()) != len(expectedValues) {
178 b.Fatalf("unexpected number of values: %d", len(rr.Values()))
179 }
180 for i := range rr.Values() {
181 if !bytes.Equal(rr.Values()[i], expectedValues[i]) {
182 b.Fatalf("unexpected values: %s %s", rr.Values()[i], expectedValues[i])
183 }
184 }
185 }
186 _, err = rr.Close()
187
188 if err != nil {
189 b.Fatal(err)
190 }
191 if rowCount != 1 {
192 b.Fatalf("unexpected rowCount: %d", rowCount)
193 }
194 }
195 })
196 }
197 }
198
199 func BenchmarkExecPreparedPossibleToCancel(b *testing.B) {
200 conn, err := pgconn.Connect(context.Background(), os.Getenv("PGX_TEST_DATABASE"))
201 require.Nil(b, err)
202 defer closeConn(b, conn)
203
204 ctx, cancel := context.WithCancel(context.Background())
205 defer cancel()
206
207 _, err = conn.Prepare(ctx, "ps1", "select 'hello'::text as a, 42::int4 as b, '2019-01-01'::date", nil)
208 require.Nil(b, err)
209
210 expectedValues := [][]byte{[]byte("hello"), []byte("42"), []byte("2019-01-01")}
211
212 b.ResetTimer()
213
214 for i := 0; i < b.N; i++ {
215 rr := conn.ExecPrepared(ctx, "ps1", nil, nil, nil)
216
217 rowCount := 0
218 for rr.NextRow() {
219 rowCount += 1
220 if len(rr.Values()) != len(expectedValues) {
221 b.Fatalf("unexpected number of values: %d", len(rr.Values()))
222 }
223 for i := range rr.Values() {
224 if !bytes.Equal(rr.Values()[i], expectedValues[i]) {
225 b.Fatalf("unexpected values: %s %s", rr.Values()[i], expectedValues[i])
226 }
227 }
228 }
229 _, err = rr.Close()
230
231 if err != nil {
232 b.Fatal(err)
233 }
234 if rowCount != 1 {
235 b.Fatalf("unexpected rowCount: %d", rowCount)
236 }
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
View as plain text