using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using MaddoShared.Benchmarks.Helpers;
using Microsoft.Extensions.Logging;
namespace MaddoShared.Benchmarks;
///
/// Benchmarks for image processing with various configurations
///
[MemoryDiagnoser]
[Config(typeof(InProcessConfig))]
public class ImageProcessingBenchmarks
{
private string _sourceDirectory;
private string _destinationDirectory;
private ImageCreationService _imageCreationStuff;
private PicSettings _picSettings;
private ILogger _logger;
private ILogger _imageCreatorLogger;
[Params(10, 50, 100)]
public int ImageCount { get; set; }
[Params(1, 2, 4, 8)]
public int MaxThreads { get; set; }
[GlobalSetup]
public void Setup()
{
// Create temp directories
var tempBase = Path.Combine(Path.GetTempPath(), "ImageBenchmarks", Guid.NewGuid().ToString());
_sourceDirectory = Path.Combine(tempBase, "Source");
_destinationDirectory = Path.Combine(tempBase, "Destination");
Directory.CreateDirectory(_sourceDirectory);
Directory.CreateDirectory(_destinationDirectory);
// Generate test images
Console.WriteLine($"Generating {ImageCount} test images...");
TestImageGenerator.GenerateTestImages(_sourceDirectory, ImageCount, width: 2000, height: 1500);
// Setup logging
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Warning); // Reduce noise during benchmarks
});
_logger = loggerFactory.CreateLogger();
_imageCreatorLogger = loggerFactory.CreateLogger();
// Setup PicSettings with default values
_picSettings = new PicSettings
{
DirectorySorgente = _sourceDirectory,
DirectoryDestinazione = _destinationDirectory,
DimStandard = 800,
DimStandardMiniatura = 200,
LarghezzaBig = 1024,
AltezzaBig = 768,
LarghezzaSmall = 200,
AltezzaSmall = 150,
CreaMiniature = true,
AggiungiScritteMiniature = false,
UsaForzaJpg = true,
UsaRotazioneAutomatica = true,
LogoAggiungi = false,
FotoGrandeDimOrigina = false,
TestoNome = false,
NomeData = false,
Suffisso = "_small",
Margine = 10,
Trasparenza = 100
};
var imageCreatorService = new ImageCreatorImageSharp(_picSettings, _imageCreatorLogger);
_imageCreationStuff = new ImageCreationService(_logger, _picSettings, imageCreatorService);
}
[GlobalCleanup]
public void Cleanup()
{
// Clean up temp directories
try
{
var tempBase = Path.GetDirectoryName(_sourceDirectory);
if (Directory.Exists(tempBase))
{
Directory.Delete(tempBase, recursive: true);
}
}
catch (Exception ex)
{
Console.WriteLine($"Cleanup error: {ex.Message}");
}
}
[IterationSetup]
public void IterationSetup()
{
// Clean destination directory before each iteration
if (Directory.Exists(_destinationDirectory))
{
Directory.Delete(_destinationDirectory, recursive: true);
}
Directory.CreateDirectory(_destinationDirectory);
}
[Benchmark(Description = "Process images in parallel with chunking")]
public async Task ProcessImagesParallelWithChunks()
{
var options = new ImageCreationService.Options
{
SourcePath = _sourceDirectory,
DestinationPath = _destinationDirectory,
MaxThreads = MaxThreads,
ChunksSize = 10,
LinearExecution = false,
AggiornaSottodirectory = false,
CreaSottocartelle = false,
FilePerCartella = 100,
SuffissoCartelle = "",
CifreContatore = 4,
NumerazioneType = NumerazioneType.Progressiva
};
var results = new ConcurrentBag();
await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None);
}
[Benchmark(Description = "Process images in parallel without chunking")]
public async Task ProcessImagesParallelWithoutChunks()
{
var options = new ImageCreationService.Options
{
SourcePath = _sourceDirectory,
DestinationPath = _destinationDirectory,
MaxThreads = MaxThreads,
ChunksSize = 0, // No chunking
LinearExecution = false,
AggiornaSottodirectory = false,
CreaSottocartelle = false,
FilePerCartella = 100,
SuffissoCartelle = "",
CifreContatore = 4,
NumerazioneType = NumerazioneType.Progressiva
};
var results = new ConcurrentBag();
await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None);
}
[Benchmark(Description = "Process images linearly")]
public async Task ProcessImagesLinear()
{
var options = new ImageCreationService.Options
{
SourcePath = _sourceDirectory,
DestinationPath = _destinationDirectory,
MaxThreads = MaxThreads,
ChunksSize = 0,
LinearExecution = true,
AggiornaSottodirectory = false,
CreaSottocartelle = false,
FilePerCartella = 100,
SuffissoCartelle = "",
CifreContatore = 4,
NumerazioneType = NumerazioneType.Progressiva
};
var results = new ConcurrentBag();
await _imageCreationStuff.ProcessImagesParallel(options, results, null, CancellationToken.None);
}
}