summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValery Piashchynski <[email protected]>2021-02-05 23:10:50 +0300
committerValery Piashchynski <[email protected]>2021-02-05 23:10:50 +0300
commit11b357c4457dfcbc1ef79478c200b794b5486b13 (patch)
tree29b512baf4d6a8ef79e19a0de3a9e642871b6d4e
parent6c8cf12de734f01a0f0cdc4d2b55973cc8d1ddf1 (diff)
Faster toString convertation (only for the english)
-rwxr-xr-xpkg/payload/payload.go9
-rwxr-xr-xpkg/pool/static_pool.go12
-rwxr-xr-xpkg/pool/static_pool_test.go31
3 files changed, 48 insertions, 4 deletions
diff --git a/pkg/payload/payload.go b/pkg/payload/payload.go
index fac36852..bebe8df1 100755
--- a/pkg/payload/payload.go
+++ b/pkg/payload/payload.go
@@ -1,5 +1,7 @@
package payload
+import "unsafe"
+
// Payload carries binary header and body to stack and
// back to the server.
type Payload struct {
@@ -12,5 +14,10 @@ type Payload struct {
// String returns payload body as string
func (p *Payload) String() string {
- return string(p.Body)
+ return toString(p.Body)
}
+
+// unsafe, but lightning fast []byte to string conversion
+func toString(data []byte) string {
+ return *(*string)(unsafe.Pointer(&data))
+} \ No newline at end of file
diff --git a/pkg/pool/static_pool.go b/pkg/pool/static_pool.go
index 23f24e27..dd52f313 100755
--- a/pkg/pool/static_pool.go
+++ b/pkg/pool/static_pool.go
@@ -4,6 +4,7 @@ import (
"context"
"os/exec"
"time"
+ "unsafe"
"github.com/spiral/errors"
"github.com/spiral/roadrunner/v2/pkg/events"
@@ -148,8 +149,8 @@ func (sp *StaticPool) Exec(p payload.Payload) (payload.Payload, error) {
}
// worker want's to be terminated
- // TODO careful with string(rsp.Context)
- if len(rsp.Body) == 0 && string(rsp.Context) == StopRequest {
+ // TODO careful with toString(rsp.Context)
+ if len(rsp.Body) == 0 && toString(rsp.Context) == StopRequest {
sp.stopWorker(w)
return sp.Exec(p)
}
@@ -178,7 +179,7 @@ func (sp *StaticPool) ExecWithContext(ctx context.Context, p payload.Payload) (p
}
// worker want's to be terminated
- if len(rsp.Body) == 0 && string(rsp.Context) == StopRequest {
+ if len(rsp.Body) == 0 && toString(rsp.Context) == StopRequest {
sp.stopWorker(w)
return sp.ExecWithContext(ctx, p)
}
@@ -323,3 +324,8 @@ func (sp *StaticPool) allocateWorkers(numWorkers uint64) ([]worker.SyncWorker, e
}
return workers, nil
}
+
+// unsafe, but lightning fast []byte to string conversion
+func toString(data []byte) string {
+ return *(*string)(unsafe.Pointer(&data))
+}
diff --git a/pkg/pool/static_pool_test.go b/pkg/pool/static_pool_test.go
index 8b1bf6a9..65e10119 100755
--- a/pkg/pool/static_pool_test.go
+++ b/pkg/pool/static_pool_test.go
@@ -645,3 +645,34 @@ func Benchmark_Pool_Echo_Replaced(b *testing.B) {
}
}
}
+
+// BenchmarkToStringUnsafe-12 566317729 1.91 ns/op 0 B/op 0 allocs/op
+// inline BenchmarkToStringUnsafe-12 1000000000 0.295 ns/op 0 B/op 0 allocs/op
+func BenchmarkToStringUnsafe(b *testing.B) {
+ testPayload := []byte("falsflasjlifjwpoihejfoiwejow{}{}{}{}jelfjasjfhwaopiehjtopwhtgohrgouahsgkljasdlfjasl;fjals;jdflkndgouwhetopwqhjtoj")
+ b.ResetTimer()
+ b.ReportAllocs()
+
+ for i := 0; i < b.N; i++ {
+ res := toString(testPayload)
+ _ = res
+ }
+}
+
+// BenchmarkToStringSafe-12 28584489 39.1 ns/op 112 B/op 1 allocs/op
+// inline BenchmarkToStringSafe-12 28926276 46.6 ns/op 128 B/op 1 allocs/op
+func BenchmarkToStringSafe(b *testing.B) {
+ testPayload := []byte("falsflasjlifjwpoihejfoiwejow{}{}{}{}jelfjasjfhwaopiehjtopwhtgohrgouahsgkljasdlfjasl;fjals;jdflkndgouwhetopwqhjtoj")
+
+ b.ResetTimer()
+ b.ReportAllocs()
+
+ for i := 0; i < b.N; i++ {
+ res := toStringNotFun(testPayload)
+ _ = res
+ }
+}
+
+func toStringNotFun(data []byte) string {
+ return string(data)
+}