簡體   English   中英

Go的PNG編碼速度很慢

[英]PNG encoding with Go is slow

我正在使用go-opencv從內置的網絡攝像頭獲取幀。 從相機獲取圖像所需的時間約為50毫秒。 編碼PNG的時間約為300毫秒。 編碼JPEG的速度快了3倍,但仍然非常慢。

為什么運行這么慢?

注意 :我已經針對NodeJS編寫了類似的代碼,在同一台機器上執行,並且在達到30fps且帶有附加圖像處理的情況下絕對沒有問題。 對我來說,這消除了方程式中的硬件問題。

我的代碼如下所示:

import (
    "fmt"
    "image/png"

    "github.com/lazywei/go-opencv/opencv"
)

camera := opencv.NewCameraCapture(0)
if camera == nil {
    panic("Unable to open camera.")
}
defer camera.Release()

for {
    if camera.GrabFrame() {
        img := camera.RetrieveFrame(1)
        if img != nil {
            frame := img.ToImage()
            buffer := new(bytes.Buffer)
            png.Encode(buffer, frame)
        } else {
            fmt.Println("Unable to capture frame")
        }
    }

}

禁用壓縮可將計算機上的編碼性能提高一個數量級。 如果您不想在標准庫之外查找png包,那可能是一個開始。

我還嘗試了BufferPool (Go 1.9中的新增功能),但是與使用零BufferPool的編碼器相比,它沒有什么區別。 也許我做錯了。 不幸的是,文檔非常簡潔。

package main

import (
    "bytes"
    "image"
    "image/png"
    "os"
    "testing"
)

func BenchmarkPNG_Encode(b *testing.B) {
    img, buf := loadImage(b)

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
            buf.Reset()
            png.Encode(buf, img)
    }
}

func BenchmarkPNG_Encoder(b *testing.B) {
    img, buf := loadImage(b)
    enc := &png.Encoder{}

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
            buf.Reset()
            enc.Encode(buf, img)
    }
}

func BenchmarkPNG_Encoder_NoCompression(b *testing.B) {
    img, buf := loadImage(b)
    enc := &png.Encoder{
            CompressionLevel: png.NoCompression,
    }

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
            buf.Reset()
            enc.Encode(buf, img)
    }
}

func loadImage(b *testing.B) (image.Image, *bytes.Buffer) {
    // foo.png PNG 1920x1053 1920x1053+0+0 8-bit sRGB 251KB 0.000u 0:00.000
    f, err := os.Open("foo.png")
    if err != nil {
            b.Fatal(err)
    }

    img, err := png.Decode(f)
    if err != nil {
            b.Fatal(err)
    }
    f.Close()

    buf := &bytes.Buffer{}
    // grow the buffer once
    (&png.Encoder{CompressionLevel: png.NoCompression}).Encode(buf, img)

    return img, buf
}

再次,這是在我的機器上,具有大約1920x1080像素的圖像-隨機屏幕截圖; 不知道這與照片有什么不同。 因人而異。

$ go test -v -bench . -benchmem 
goos: linux
goarch: amd64
BenchmarkPNG_Encode-8                         10         119289121 ns/op          884964 B/op         38 allocs/op
BenchmarkPNG_Encoder-8                        10         118001658 ns/op          884932 B/op         37 allocs/op
BenchmarkPNG_Encoder_NoCompression-8         100          13050664 ns/op          807156 B/op        212 allocs/op

有趣的是,沒有壓縮比使用壓縮導致更多的分配。

為什么運行這么慢?

測量! Go有內置的好分析工具,例如go test

PNG編碼器很可能是純的,“未優化”的Go。 如果這還不夠快,那么您可能要考慮提供更快的PNG編碼器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM