docker build -t comparison .
docker run -v "$HOME/Pictures/my_picture.png:/app/example.png" comparison example.png 2>/dev/null
Created
October 31, 2024 15:08
-
-
Save Loupax/46a4ca7cf9c8c1b8ed6bae5bae6d306d to your computer and use it in GitHub Desktop.
Image Processing Memory Footprint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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