Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"image/color"
"testing"
"time"

"github.com/go-gfx/gfx/raster"
"github.com/go-pdfkit/reader"
Expand Down Expand Up @@ -115,3 +116,50 @@ func inked(img *raster.Image) int {
}
return n
}

// pairedBest draws two documents ALTERNATELY and returns the shortest each
// took, which is what a test comparing the two should ask for.
//
// Three runs of one followed by three of the other is enough to fail on a busy
// machine: the witness can take all three of its turns in a quiet moment and
// the subject all three of its own under a spike, and the ratio then reports
// the machine rather than the code. Alternating puts every spike inside one
// ROUND, where it falls on both sides.
//
// Seen once, 2026-10-04: TestAThreeComponentJPEGIsCachedOnItsSampleTriple
// reported 8.9x at a load average of 59, and the same build passed three times
// in a row a minute later. The ratio was real and it was a ratio of two
// different moments.
//
// MEASURED, because that failure could not be reproduced on demand. A
// throwaway test computed the ratio both ways on the same work, forty rounds
// per scheme per run, under load:
//
// max of 40 max of 40 max of 40 over 3x
// blocked 1.61 2.27 8.80 1 of 120
// interleaved 1.53 1.52 1.61 0 of 120
//
// The 8.80 is the failure reproduced. The blocked scheme also returned 0.50
// once, which says the calibrated subject ran twice as fast as the device
// witness -- impossible for the quantity being measured, and the plainest
// demonstration that its two minima come from two different moments.
//
// A warm-up draw of each is the caller's business, and all three callers do it:
// the first draw of a page pays for whatever is cached once.
func pairedBest(t *testing.T, witness, subject *reader.Document, rounds int) (time.Duration, time.Duration) {
t.Helper()
w, s := time.Duration(1<<62), time.Duration(1<<62)
for i := 0; i < rounds; i++ {
start := time.Now()
draw(t, witness, Options{})
if took := time.Since(start); took < w {
w = took
}
start = time.Now()
draw(t, subject, Options{})
if took := time.Since(start); took < s {
s = took
}
}
return w, s
}
52 changes: 9 additions & 43 deletions jpegspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"image"
"image/jpeg"
"testing"
"time"

"github.com/go-pdfkit/reader"
)
Expand Down Expand Up @@ -279,20 +278,9 @@ func TestAOneComponentJPEGIsConvertedOncePerLevelRatherThanOncePerPixel(t *testi
draw(t, gradientJPEGPage(t, side, device), Options{})
draw(t, gradientJPEGPage(t, side, calibrated), Options{})

best := func(space func(*reader.Writer) reader.Object) time.Duration {
d := gradientJPEGPage(t, side, space)
out := time.Duration(1 << 62)
for i := 0; i < 3; i++ {
start := time.Now()
draw(t, d, Options{})
if took := time.Since(start); took < out {
out = took
}
}
return out
}
witness := best(device)
subject := best(calibrated)
witness, subject := pairedBest(t,
gradientJPEGPage(t, side, device),
gradientJPEGPage(t, side, calibrated), 3)
if subject > 3*witness {
t.Errorf("a calibrated grey JPEG took %v against DeviceGray's %v (%.1fx); "+
"the colour space is being asked per pixel rather than per level",
Expand Down Expand Up @@ -451,20 +439,9 @@ func TestAThreeComponentJPEGIsCachedOnItsSampleTriple(t *testing.T) {
draw(t, rgbJPEGPage(t, side, deviceRGB, fill), Options{})
draw(t, rgbJPEGPage(t, side, calRGB, fill), Options{})

best := func(space func(*reader.Writer) reader.Object) time.Duration {
d := rgbJPEGPage(t, side, space, fill)
out := time.Duration(1 << 62)
for i := 0; i < 3; i++ {
start := time.Now()
draw(t, d, Options{})
if took := time.Since(start); took < out {
out = took
}
}
return out
}
witness := best(deviceRGB)
subject := best(calRGB)
witness, subject := pairedBest(t,
rgbJPEGPage(t, side, deviceRGB, fill),
rgbJPEGPage(t, side, calRGB, fill), 3)
if subject > 3*witness {
t.Errorf("a calibrated RGB JPEG took %v against DeviceRGB's %v (%.1fx); "+
"the colour space is being asked per pixel rather than per distinct triple",
Expand Down Expand Up @@ -634,20 +611,9 @@ func TestManySmallPicturesDoNotEachPayForTheTable(t *testing.T) {
draw(t, manyTinyJPEGsPage(t, n, deviceRGB), Options{})
draw(t, manyTinyJPEGsPage(t, n, calRGB), Options{})

best := func(space func(*reader.Writer) reader.Object) time.Duration {
d := manyTinyJPEGsPage(t, n, space)
out := time.Duration(1 << 62)
for i := 0; i < 3; i++ {
start := time.Now()
draw(t, d, Options{})
if took := time.Since(start); took < out {
out = took
}
}
return out
}
witness := best(deviceRGB)
subject := best(calRGB)
witness, subject := pairedBest(t,
manyTinyJPEGsPage(t, n, deviceRGB),
manyTinyJPEGsPage(t, n, calRGB), 3)
if subject > 3*witness {
t.Errorf("%d small calibrated pictures took %v against DeviceRGB's %v (%.1fx); "+
"each picture is paying for its own cache", n, subject, witness,
Expand Down
Loading