Closed simongui closed 8 years ago
Redeo will be naturally slower than Redis, since Go is simply a few magnitudes slower than C. Looking at your profile, it doesn't look as if there is much to improve. Did you try it with Go 1.7?
Yeah that was run with Go 1.7. I'm not sure I agree that this performance is due to Go and that improvements can't be made. If you look at the Techempower HTTP benchmarks you'll see fasthttp
which is implemented in Go and parses a much more complicated HTTP protocol is at the 3rd and 4th position among some of the fastest HTTP servers competing against C and C++.
https://www.techempower.com/benchmarks/#section=data-r12&hw=peak&test=plaintext
Here's a reasonably fast Go implementation of a redis ping server:
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"log"
"net"
"strconv"
)
var (
ping = []byte("PING")
pong = []byte("+PONG\r\n")
)
func main() {
if err := run(); err != nil {
log.Fatal(err.Error())
}
}
func run() error {
l, err := net.Listen("tcp", ":9736")
if err != nil {
return err
}
defer l.Close()
for {
conn, err := l.Accept()
if err != nil {
return err
}
go handle(conn)
}
}
func handle(conn net.Conn) {
defer conn.Close()
buf := bufio.NewReader(conn)
void := make([]byte, 0, 1024)
for {
if err := process(buf, void); err != nil {
if err != io.EOF {
log.Println(err.Error())
}
return
}
conn.Write(pong)
}
}
func process(buf *bufio.Reader, void []byte) error {
line, prefix, err := buf.ReadLine()
if err != nil {
return err
} else if prefix || len(line) == 0 {
return fmt.Errorf("bad request")
}
switch line[0] {
case '*':
n, err := strconv.Atoi(string(line[1:]))
if err != nil {
return err
}
for i := 0; i < n; i++ {
if err := process(buf, void); err != nil {
return err
}
}
case '$':
n, err := strconv.Atoi(string(line[1:]))
if err != nil {
return err
}
void = void[:n+2]
if _, err := buf.Read(void); err != nil {
return err
}
default:
if !bytes.Equal(line, ping) {
return fmt.Errorf("bad request: %s", strconv.Quote(string(line)))
}
}
return nil
}
And here are my benchmarks, compared against native redis:
$ redis-benchmark -t ping -p 9736 -q -P 100
PING_INLINE: 787401.56 requests per second
PING_BULK: 675675.69 requests per second
$ redis-benchmark -t ping -p 6379 -q -P 100
PING_INLINE: 1408450.62 requests per second
PING_BULK: 2325581.25 requests per second
Redis is just really, really fast :)
Even with empty handlers that basically NOOP the performance of this library is still lacking compared to Redis itself which is doing more work. I wonder if the bottleneck could be removed? I haven't looked into it yet but I thought I would report some benchmarks.
Redis
Redeo
Server code is as follows.
Profiling shows the following.