| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /**
- * Benchmark - Base classes for performance benchmarks
- *
- * Provides common infrastructure for measuring operation performance
- * including timing, iteration management, and result collection.
- *
- * Uses abstract classes with async methods instead of delegates,
- * since Vala doesn't support async delegates.
- *
- * @version 0.1
- * @since 0.1
- */
- namespace Implexus.Tools.Perf {
- /**
- * Holds the results of a single benchmark operation.
- */
- public class BenchmarkResults : Object {
- public string operation { get; set; }
- public int iterations { get; set; }
- public double total_time_ms { get; set; }
- public int batch_size { get; set; default = 0; }
-
- public double avg_time_ms {
- get { return iterations > 0 ? total_time_ms / iterations : 0; }
- }
-
- public double avg_item_time_ms {
- get {
- if (batch_size <= 0 || iterations <= 0) {
- return avg_time_ms;
- }
- int total_items = batch_size * iterations;
- return total_time_ms / total_items;
- }
- }
-
- public double ops_per_second {
- get { return avg_time_ms > 0 ? 1000.0 / avg_time_ms : 0; }
- }
-
- public double items_per_second {
- get { return avg_item_time_ms > 0 ? 1000.0 / avg_item_time_ms : 0; }
- }
-
- public int total_items {
- get { return batch_size > 0 ? batch_size * iterations : iterations; }
- }
-
- public BenchmarkResults() {
- operation = "";
- iterations = 0;
- total_time_ms = 0;
- batch_size = 0;
- }
- }
- /**
- * Tracks paths for deferred cleanup.
- */
- public class CleanupTracker : Object {
- private GLib.List<string> _documents;
- private GLib.List<string> _indices;
- private GLib.List<string> _catalogues;
- private GLib.List<string> _categories;
- private GLib.List<string> _containers;
-
- public CleanupTracker() {
- _documents = new GLib.List<string>();
- _indices = new GLib.List<string>();
- _catalogues = new GLib.List<string>();
- _categories = new GLib.List<string>();
- _containers = new GLib.List<string>();
- }
-
- public void add_document(string path) { _documents.append(path); }
- public void add_index(string path) { _indices.append(path); }
- public void add_catalogue(string path) { _catalogues.append(path); }
- public void add_category(string path) { _categories.append(path); }
- public void add_container(string path) { _containers.append(path); }
-
- public unowned GLib.List<string> get_documents() { return _documents; }
- public unowned GLib.List<string> get_indices() { return _indices; }
- public unowned GLib.List<string> get_catalogues() { return _catalogues; }
- public unowned GLib.List<string> get_categories() { return _categories; }
-
- public GLib.List<string> get_containers_reversed() {
- var reversed = new GLib.List<string>();
- foreach (unowned string path in _containers) {
- reversed.prepend(path);
- }
- return reversed;
- }
-
- public int get_total_count() {
- return (int)_documents.length() + (int)_indices.length() +
- (int)_catalogues.length() + (int)_categories.length() +
- (int)_containers.length();
- }
- }
- /**
- * Abstract base class for async operations (replaces async delegates).
- */
- public abstract class AsyncOperation : Object {
- public int iteration { get; set; }
- public abstract async void execute_async() throws Error;
- }
- /**
- * Abstract base class for benchmarks.
- */
- public abstract class Benchmark : Object {
- public Core.Engine _engine;
- public BenchmarkConfig _config;
- public CleanupTracker _cleanup_tracker;
-
- public abstract string name { get; }
-
- protected Benchmark(Core.Engine engine, BenchmarkConfig config) {
- _engine = engine;
- _config = config;
- _cleanup_tracker = new CleanupTracker();
- }
-
- public void set_cleanup_tracker(CleanupTracker tracker) {
- _cleanup_tracker = tracker;
- }
-
- public abstract async void run_async(Results results) throws Error;
-
- public void run(Results results) throws Error {
- var loop = new MainLoop();
- Error? error = null;
-
- run_async.begin(results, (obj, res) => {
- try {
- run_async.end(res);
- } catch (Error e) {
- error = e;
- }
- loop.quit();
- });
- loop.run();
-
- if (error != null) {
- throw (!) error;
- }
- }
-
- public async BenchmarkResults measure_async(string operation, int iterations, AsyncOperation op) throws Error {
- var timer = new Timer();
- timer.start();
-
- for (int i = 0; i < iterations; i++) {
- op.iteration = i;
- yield op.execute_async();
- }
-
- timer.stop();
- var elapsed = timer.elapsed() * 1000.0;
-
- return new BenchmarkResults() {
- operation = operation,
- iterations = iterations,
- total_time_ms = elapsed
- };
- }
-
- public async void cleanup_path_async(Core.EntityPath path) {
- try {
- var entity = yield _engine.get_entity_or_null_async(path);
- if (entity != null) {
- yield ((!) entity).delete_async();
- }
- } catch (Error e) {
- // Ignore cleanup errors
- }
- }
-
- public async Core.Entity ensure_container_async(Core.EntityPath path, string name) throws Error {
- var existing = yield _engine.get_entity_or_null_async(path);
- if (existing != null) {
- return (!) existing;
- }
-
- var parent_path = path.parent;
- Core.Entity parent;
- if (parent_path != null && !((!) parent_path).is_root) {
- parent = yield ensure_container_async((!) parent_path, ((!) parent_path).name);
- } else {
- parent = yield _engine.get_root_async();
- }
-
- return yield parent.create_container_async(name);
- }
- }
- }
|