parser: Optimize multi bulk request parsing.

This commit is contained in:
Vladimir Mihailenco 2012-08-20 12:00:59 +03:00
parent 5e2cce4853
commit 2f5c2aa6be
3 changed files with 25 additions and 21 deletions

View File

@ -114,16 +114,12 @@ func _parseReply(rd reader, useIfaceSlice bool) (interface{}, error) {
}
if useIfaceSlice {
vals := make([]interface{}, 0)
if len(line) == 2 && line[1] == '0' {
return vals, nil
}
numReplies, err := strconv.ParseInt(string(line[1:]), 10, 64)
if err != nil {
return nil, err
}
vals := make([]interface{}, 0, numReplies)
for i := int64(0); i < numReplies; i++ {
v, err := parseReply(rd)
if err == Nil {
@ -137,16 +133,12 @@ func _parseReply(rd reader, useIfaceSlice bool) (interface{}, error) {
return vals, nil
} else {
vals := make([]string, 0)
if len(line) == 2 && line[1] == '0' {
return vals, nil
}
numReplies, err := strconv.ParseInt(string(line[1:]), 10, 64)
if err != nil {
return nil, err
}
vals := make([]string, 0, numReplies)
for i := int64(0); i < numReplies; i++ {
v, err := parseReply(rd)
if err != nil {

View File

View File

@ -35,21 +35,17 @@ func (t *RequestTest) TearDownTest(c *C) {}
//------------------------------------------------------------------------------
func (t *RequestTest) BenchmarkStatusReq(c *C) {
func (t *RequestTest) benchmarkReq(c *C, reqString string, req redis.Req, checker Checker, expected interface{}) {
c.StopTimer()
lineReader := NewLineReader([]byte("+OK\r\n"))
lineReader := NewLineReader([]byte(reqString))
rd := bufio.NewReaderSize(lineReader, 1024)
req := redis.NewStatusReq()
for i := 0; i < 10; i++ {
vI, err := req.ParseReply(rd)
vIface, err := req.ParseReply(rd)
c.Check(err, IsNil)
c.Check(vI, Equals, "OK")
req.SetVal(vI)
c.Check(req.Err(), IsNil)
c.Check(req.Val(), Equals, "OK")
c.Check(vIface, checker, expected)
req.SetVal(vIface)
}
c.StartTimer()
@ -57,7 +53,23 @@ func (t *RequestTest) BenchmarkStatusReq(c *C) {
for i := 0; i < c.N; i++ {
v, _ := req.ParseReply(rd)
req.SetVal(v)
req.Err()
req.Val()
}
}
func (t *RequestTest) BenchmarkStatusReq(c *C) {
t.benchmarkReq(c, "+OK\r\n", redis.NewStatusReq(), Equals, "OK")
}
func (t *RequestTest) BenchmarkStringReq(c *C) {
t.benchmarkReq(c, "$5\r\nhello\r\n", redis.NewStringReq(), Equals, "hello")
}
func (t *RequestTest) BenchmarkStringSliceReq(c *C) {
t.benchmarkReq(
c,
"*2\r\n$5\r\nhello\r\n$5\r\nhello\r\n",
redis.NewStringSliceReq(),
DeepEquals,
[]string{"hello", "hello"},
)
}