Open
Description
Perhaps this doesn't qualify as an issue per-se, but I wanted to use draw2d as the renderer in my program (instead of Cairo). However, even in simple cases, draw2dimg performs at least 10-30x worse than the equivalent Cairo code via cgo.
Maybe I'm doing something wrong? (I hope so)
Simple benchmark test below draws filled squares with an outline, performing ~30x worse on draw2d than Cairo. When the drawn surface is 1:1 blitted to another surface, the gap closes to ~10x
package main
import (
"flag"
"image"
"image/color"
"image/png"
"log"
"os"
"testing"
"github.com/ungerik/go-cairo"
"github.com/llgcode/draw2d/draw2dimg"
)
var dumpImage bool
func TestMain(m *testing.M) {
flag.BoolVar(&dumpImage, "dump", false, "Dump a PNG image from each benchmark for comparison")
flag.Parse()
os.Exit(m.Run())
}
func BenchmarkDraw2D(b *testing.B) {
img := image.NewRGBA(image.Rect(0, 0, 500, 500))
ctx := draw2dimg.NewGraphicContext(img)
for n := 0; n < b.N; n++ {
ctx.SetStrokeColor(color.RGBA{0xff, 0x00, 0x00, 0xff})
ctx.SetFillColor(color.RGBA{0x4d, 0x4d, 0x4d, 0xff})
ctx.SetLineWidth(2)
ctx.MoveTo(1, 1)
ctx.LineTo(499, 1)
ctx.LineTo(499, 499)
ctx.LineTo(1, 499)
ctx.Close()
ctx.FillStroke()
}
if dumpImage {
f, err := os.Create("draw2d.png")
if err != nil {
log.Fatal(err)
}
if err := png.Encode(f, img); err != nil {
f.Close()
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
}
func BenchmarkCairo(b *testing.B) {
img := cairo.NewSurface(cairo.FORMAT_ARGB32, 500, 500)
for n := 0; n < b.N; n++ {
img.Rectangle(0, 0, 500, 500)
img.SetSourceRGB(0.3, 0.3, 0.3)
img.SetLineWidth(4)
img.FillPreserve()
img.SetSourceRGB(1.0, 0.0, 0.0)
img.Stroke()
}
if dumpImage {
img.WriteToPNG("cairo.png")
}
}
Results:
$ go test -v -bench=. -test.parallel 1
goos: linux
goarch: amd64
pkg: github.com/usedbytes/drawbench
BenchmarkDraw2D-4 1000 2049011 ns/op
BenchmarkCairo-4 30000 50037 ns/op
PASS
ok github.com/usedbytes/drawbench 4.278s
The README says that draw2d is a pure-go alternative to Cairo, but unfortunately the performance difference is too high for my use-case.
Metadata
Metadata
Assignees
Labels
No labels