diff --git a/args.go b/args.go index 951028b..78401be 100644 --- a/args.go +++ b/args.go @@ -458,6 +458,12 @@ func decodeArg(dst, src []byte, decodePlus bool) []byte { } func decodeArgAppend(dst, src []byte, decodePlus bool) []byte { + if bytes.IndexByte(src, '%') < 0 && (!decodePlus || bytes.IndexByte(src, '+') < 0) { + // fast path: src doesn't contain encoded chars + return append(dst, src...) + } + + // slow path for i, n := 0, len(src); i < n; i++ { c := src[i] if c == '%' { diff --git a/bytesconv_timing_test.go b/bytesconv_timing_test.go index bd416d1..53f04ac 100644 --- a/bytesconv_timing_test.go +++ b/bytesconv_timing_test.go @@ -165,3 +165,23 @@ func BenchmarkLowercaseBytesMixed(b *testing.B) { } }) } + +func BenchmarkAppendUnquotedArgFastPath(b *testing.B) { + src := []byte("foobarbaz no quoted chars fdskjsdf jklsdfdfskljd;aflskjdsaf fdsklj fsdkj fsdl kfjsdlk jfsdklj fsdfsdf sdfkflsd") + b.RunParallel(func(pb *testing.PB) { + var dst []byte + for pb.Next() { + dst = AppendUnquotedArg(dst[:0], src) + } + }) +} + +func BenchmarkAppendUnquotedArgSlowPath(b *testing.B) { + src := []byte("D0%B4%20%D0%B0%D0%B2%D0%BB%D0%B4%D1%84%D1%8B%D0%B0%D0%BE%20%D1%84%D0%B2%D0%B6%D0%BB%D0%B4%D1%8B%20%D0%B0%D0%BE") + b.RunParallel(func(pb *testing.PB) { + var dst []byte + for pb.Next() { + dst = AppendUnquotedArg(dst[:0], src) + } + }) +}