Skip to content

Commit

Permalink
reorganize utils
Browse files Browse the repository at this point in the history
  • Loading branch information
tayloraswift committed Jan 30, 2024
1 parent 8e6ac88 commit 3a3d58b
Show file tree
Hide file tree
Showing 132 changed files with 6,827 additions and 9,392 deletions.
Binary file added Benchmarks/Compression/C/main
Binary file not shown.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,29 @@ func clock() -> Int
}

#else
#warning("clock() function not imported for this platform, internal benchmarks not built (please open an issue at https://github.com/kelvin13/swift-png/issues)")
#warning("clock() function not imported for this platform, internal benchmarks not built (please open an issue at https://github.com/tayloraswift/swift-png/issues)")
#endif

#if os(macOS) || os(Linux)

// internal benchmarking functions, to measure module boundary overhead
enum Benchmark
enum Benchmark
{
enum Encode
enum Encode
{
struct Blob
{
private(set)
private(set)
var buffer:[UInt8] = []
}
}
}
extension Benchmark.Encode.Blob:PNG.Bytestream.Destination
extension Benchmark.Encode.Blob:PNG.Bytestream.Destination
{
mutating
mutating
func write(_ data:[UInt8]) -> Void?
{
self.buffer.append(contentsOf: data)
self.buffer.append(contentsOf: data)
return ()
}
}
Expand All @@ -56,23 +56,23 @@ extension Benchmark.Encode
func rgba8(level:Int, path:String, trials:Int) -> ([(time:Int, hash:Int)], Int)
{
guard let image:PNG.Data.Rectangular = try? .decompress(path: path)
else
else
{
fatalError("failed to decode test image '\(path)'")
}
let results:[(time:Int, size:Int, hash:Int)] = (0 ..< trials).map

let results:[(time:Int, size:Int, hash:Int)] = (0 ..< trials).map
{
_ in
_ in
// sleep for 0.1s between runs to emulate a “cold” start
nanosleep([timespec.init(tv_sec: 0, tv_nsec: 100_000_000)], nil)
var blob:Blob = .init()
do
do
{
let start:Int = clock()

try image.compress(stream: &blob, level: level)

let stop:Int = clock()
return (stop - start, blob.buffer.count, .init(blob.buffer.last ?? 0))
}
Expand All @@ -81,43 +81,43 @@ extension Benchmark.Encode
fatalError("\(error)")
}
}

return (results.map{ (time: $0.time, hash: $0.hash) }, results.map(\.size).min() ?? 0)
}
}

func main() throws
{
guard CommandLine.arguments.count == 4,
guard CommandLine.arguments.count == 4,
let level:Int = Int.init(CommandLine.arguments[1]),
let trials:Int = Int.init(CommandLine.arguments[3])
else

else
{
fatalError("usage: \(CommandLine.arguments.first ?? "") <compression-level:0 ... 9> <image> <trials>")
}

let path:String = CommandLine.arguments[2]

guard 0 ... 13 ~= level
else
else
{
fatalError("compression level must be an integer from 0 to 13")
}
#if INTERNAL_BENCHMARKS
let (results, size):([(time:Int, hash:Int)], Int) =

#if INTERNAL_BENCHMARKS
let (results, size):([(time:Int, hash:Int)], Int) =
__Entrypoint.Benchmark.Encode.rgba8(level: level, path: path, trials: trials)
#else
let (results, size):([(time:Int, hash:Int)], Int) =
#else
let (results, size):([(time:Int, hash:Int)], Int) =
Benchmark.Encode.rgba8(level: level, path: path, trials: trials)
#endif

let string:String = results.map
{
"\(1000.0 * .init($0.time) / .init(CLOCKS_PER_SEC))"
{
"\(1000.0 * .init($0.time) / .init(CLOCKS_PER_SEC))"
}.joined(separator: " ")

print("\(string), \(size)")
}

Expand Down
Binary file added Benchmarks/Decompression/C/main
Binary file not shown.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,58 +24,58 @@ func clock() -> Int
}

#else
#warning("clock() function not imported for this platform, internal benchmarks not built (please open an issue at https://github.com/kelvin13/swift-png/issues)")
#warning("clock() function not imported for this platform, internal benchmarks not built (please open an issue at https://github.com/tayloraswift/swift-png/issues)")
#endif

#if os(macOS) || os(Linux)

// internal benchmarking functions, to measure module boundary overhead
enum Benchmark
enum Benchmark
{
enum Decode
enum Decode
{
struct Blob
{
private
let buffer:[UInt8]
private(set)
var count:Int
var count:Int
}
}
}
extension Benchmark.Decode.Blob:PNG.Bytestream.Source
extension Benchmark.Decode.Blob:PNG.Bytestream.Source
{
static
func load(path:String) -> Self?
static
func load(path:String) -> Self?
{
System.File.Source.open(path: path)
System.File.Source.open(path: path)
{
(file:inout System.File.Source) -> Self? in
guard let count:Int = file.count,
(file:inout System.File.Source) -> Self? in
guard let count:Int = file.count,
let buffer:[UInt8] = file.read(count: count)
else
else
{
return nil
return nil
}
return .init(buffer: buffer, count: count)
} ?? nil
} ?? nil
}
mutating

mutating
func read(count:Int) -> [UInt8]?
{
guard count <= self.count
else
guard count <= self.count
else
{
return nil
return nil
}
let data:[UInt8] = .init(self.buffer.suffix(self.count).prefix(count))
self.count -= count
self.count -= count
return data
}
mutating
func reload()

mutating
func reload()
{
self.count = self.buffer.count
}
Expand All @@ -86,25 +86,25 @@ extension Benchmark.Decode
func rgba8(path:String, trials:Int) -> [(time:Int, hash:Int)]
{
guard var blob:Blob = .load(path: path)
else
else
{
fatalError("could not read file '\(path)'")
}
return (0 ..< trials).map

return (0 ..< trials).map
{
_ in
_ in
// sleep for 0.1s between runs to emulate a “cold” start
nanosleep([timespec.init(tv_sec: 0, tv_nsec: 100_000_000)], nil)
blob.reload()
do

do
{
let start:Int = clock()

let image:PNG.Data.Rectangular = try .decompress(stream: &blob)
let pixels:[PNG.RGBA<UInt8>] = image.unpack(as: PNG.RGBA<UInt8>.self)

let stop:Int = clock()
return (stop - start, .init(pixels.last?.r ?? 0))
}
Expand All @@ -118,22 +118,22 @@ extension Benchmark.Decode

func main() throws
{
guard CommandLine.arguments.count == 3,
guard CommandLine.arguments.count == 3,
let trials:Int = Int.init(CommandLine.arguments[2])
else

else
{
fatalError("usage: \(CommandLine.arguments.first ?? "") <image> <trials>")
}

let path:String = CommandLine.arguments[1]
#if INTERNAL_BENCHMARKS

#if INTERNAL_BENCHMARKS
let times:[Int] = __Entrypoint.Benchmark.Decode.rgba8(path: path, trials: trials).map(\.time)
#else
#else
let times:[Int] = Benchmark.Decode.rgba8(path: path, trials: trials).map(\.time)
#endif

print(times.map{ "\(1000.0 * .init($0) / .init(CLOCKS_PER_SEC))" }.joined(separator: " "))
}

Expand Down
Loading

0 comments on commit 3a3d58b

Please sign in to comment.