Skip to content

Instantly share code, notes, and snippets.

@Loupax
Created October 31, 2024 15:08
Show Gist options
  • Save Loupax/46a4ca7cf9c8c1b8ed6bae5bae6d306d to your computer and use it in GitHub Desktop.
Save Loupax/46a4ca7cf9c8c1b8ed6bae5bae6d306d to your computer and use it in GitHub Desktop.
Image Processing Memory Footprint

How to use

docker build -t comparison .
docker run -v "$HOME/Pictures/my_picture.png:/app/example.png" comparison example.png 2>/dev/null
FROM golang:1.20-alpine3.18
RUN apk add --no-cache -U git build-base libwebp-tools vips-dev
WORKDIR /app
COPY . .
# Builds the server
RUN go build -o app main.go
ENTRYPOINT ["./app"]
package main
import (
"bytes"
"fmt"
"image"
_ "image/png" // or other formats as needed
"os"
"runtime"
"github.com/davidbyttow/govips/v2/vips"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: app <filename>")
os.Exit(1)
}
filePath := os.Args[1]
// Output actual file size in bytes
fileSize, err := getFileSize(filePath)
if err != nil {
panic(err)
}
fmt.Printf("File size on disk: %d bytes\n", fileSize)
// Track memory usage for standard library decoding
stdLibAlloc := measureMemoryUsage(func() {
loadWithStdLib(filePath)
})
// Track memory usage for govips processing
govipsAlloc := measureMemoryUsage(func() {
loadWithGovips(filePath)
})
fmt.Printf("Memory used with standard library: %d bytes\n", stdLibAlloc)
fmt.Printf("Memory used with govips: %d bytes\n", govipsAlloc)
}
func getFileSize(filePath string) (int64, error) {
fileInfo, err := os.Stat(filePath)
if err != nil {
return 0, err
}
return fileInfo.Size(), nil
}
func loadWithStdLib(filePath string) {
file, err := os.Open(filePath)
if err != nil {
panic(err)
}
defer file.Close()
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
var buf bytes.Buffer
_ = img // Use `img` if needed, e.g., to render or further process it
_ = buf // Optional: encode to another format if needed
}
func loadWithGovips(filePath string) {
vips.Startup(nil)
defer vips.Shutdown()
file, err := os.Open(filePath)
if err != nil {
panic(err)
defer file.Close()
image, err := vips.NewImageFromFile(filePath)
if err != nil {
panic(err)
}
defer image.Close()
image.Thumbnail(500, 500, vips.InterestingNone)
}
// measureMemoryUsage calculates memory allocation difference before and after the function
func measureMemoryUsage(fn func()) uint64 {
var memBefore, memAfter runtime.MemStats
runtime.GC()
runtime.ReadMemStats(&memBefore)
fn()
runtime.ReadMemStats(&memAfter)
return memAfter.Alloc - memBefore.Alloc
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment