GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Reuse one stream in codec benchmarks by JimBobSquarePants · Pull Request #3272 · SixLabors/ImageSharp

Conversation

@JimBobSquarePants

@JimBobSquarePants JimBobSquarePants commented Nov 12, 2026

Copy link
Copy Markdown
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

The codec benchmarks created a new MemoryStream in each benchmark call. The timing then included the growth and copies of that stream, and Gen2 collections for its large arrays. In production, a caller would use a recycled stream. This PR applies the change from the BMP benchmarks in #3271 to the other codec benchmarks.

Each changed benchmark now uses one stream for both libraries:

  • Encode benchmarks write into one MemoryStream that [GlobalSetup] creates. Each call sets Position = 0.
  • Decode benchmarks read from one read-only MemoryStream over the input bytes. Each call sets Position = 0.
  • [GlobalCleanup] disposes the stream.

The results now measure the codec, not the growth of a new stream.

Special cases:

  • EncodeTiff calls SetLength(0) instead of Position = 0. With a rewound stream, the GDI+ TIFF encoder threw ExternalException ("A generic error occurred in GDI+.") for None and Ccitt1D.
  • DecodeJpeg_ImageSpecific gives Skia an SKManagedStream(stream, false). SKCodec.Create(Stream) disposes the stream together with the codec.
  • In DecodeTga, ImageMagick and ImageSharp read the shared stream. Pfim still reads the byte array.
  • EncodeJxl used a new pooled ChunkedMemoryStream in each call. It now uses the shared MemoryStream. I updated Codecs/Jxl/README.md to match.

I ran each changed benchmark and replaced the result table in its comment. IdentifyJpeg, EncodeJxl, EncodeIndexedPng and EncodeGif_CoarsePaletteEncoder get their first table. The old table of DecodeJpegParseStreamOnly was outside the class. The new table is inside the class.

These benchmarks already reused their stream, so I did not change them: DecodeEncodeGif, DecodeJpeg, EncodeJpegComparison, EncodeJpegFeatures, EncodeJpegIcc and EncodeTiffIcc.

This change touches only benchmark code, so it adds no tests.

Changed files in tests/ImageSharp.Benchmarks/Codecs:

  • Exr/DecodeExr.cs
  • Gif/DecodeGif.cs
  • Gif/EncodeGif.cs
  • Heif/DecodeHeif.cs
  • Heif/EncodeHeif.cs
  • Jpeg/DecodeJpegParseStreamOnly.cs
  • Jpeg/DecodeJpeg_ImageSpecific.cs
  • Jpeg/IdentifyJpeg.cs
  • Jxl/EncodeJxl.cs
  • Jxl/README.md
  • Png/DecodePng.cs
  • Png/EncodeIndexedPng.cs
  • Png/EncodePng.cs
  • Tga/DecodeTga.cs
  • Tga/EncodeTga.cs
  • Tiff/DecodeTiff.cs
  • Tiff/DecodeTiffIcc.cs
  • Tiff/EncodeTiff.cs
  • Webp/DecodeWebp.cs
  • Webp/EncodeWebp.cs

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
JimBobSquarePants added 2 commits November 12, 2026 23:48
@JimBobSquarePants
Reuse one stream in codec benchmarks
fe27f42
Each codec benchmark now reuses one MemoryStream for both libraries.
Each call rewinds the stream, so the results measure the codec and
not the growth of a new stream. EncodeTiff truncates the stream
instead, because the GDI+ TIFF encoder fails on leftover bytes.

Update the result tables from new runs.
@JimBobSquarePants
Merge branch 'main' into js/perf-codec-benchmarks
535d9b1
@JimBobSquarePants
JimBobSquarePants merged commit 407ce6b into main Nov 13, 2026
12 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@JimBobSquarePants
JimBobSquarePants deleted the js/perf-codec-benchmarks branch November 13, 2026 01:21
@JimBobSquarePants JimBobSquarePants added the unit tests label Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

unit tests

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@JimBobSquarePants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.