CategoryBenchmark.vala 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /**
  2. * CategoryBenchmark - Benchmarks for Category entity operations
  3. *
  4. * Measures performance of category creation, member enumeration,
  5. * and predicate evaluation.
  6. *
  7. * @version 0.1
  8. * @since 0.1
  9. */
  10. namespace Implexus.Tools.Perf {
  11. /**
  12. * Benchmark for Category entity operations.
  13. *
  14. * Tests:
  15. * - create_category: Creating categories with predicates
  16. * - get_members: Enumerating category members
  17. * - predicate_evaluation: Testing predicate matching performance
  18. * - create_category_complex: Creating categories with complex predicates
  19. * - create_category_bool: Creating categories with boolean predicates
  20. * - contains_document: Checking document membership
  21. */
  22. public class CategoryBenchmark : Benchmark {
  23. /**
  24. * {@inheritDoc}
  25. */
  26. public override string name { get { return "Category"; } }
  27. /**
  28. * Creates a new CategoryBenchmark.
  29. *
  30. * @param engine The engine to benchmark
  31. * @param config The benchmark configuration
  32. */
  33. public CategoryBenchmark(Core.Engine engine, BenchmarkConfig config) {
  34. base(engine, config);
  35. }
  36. /**
  37. * {@inheritDoc}
  38. */
  39. public override async void run_async(Results results) throws Error {
  40. // Setup: Create test documents
  41. var parent_path = new Core.EntityPath("/perf-test/categories");
  42. yield ensure_container_async(new Core.EntityPath("/perf-test"), "perf-test");
  43. _cleanup_tracker.add_container(new Core.EntityPath("/perf-test").to_string());
  44. yield cleanup_path_async(parent_path);
  45. var root = yield _engine.get_root_async();
  46. var perf_test = yield root.get_child_async("perf-test");
  47. var parent_container = yield perf_test.create_container_async("categories");
  48. _cleanup_tracker.add_container(parent_path.to_string());
  49. int test_doc_count = _config.test_doc_count;
  50. int quick_iterations = _config.quick_iterations;
  51. int iterations = _config.iterations;
  52. // Create test documents with category property
  53. print(" Setting up test documents (%d documents)...\n", test_doc_count);
  54. for (int i = 0; i < test_doc_count; i++) {
  55. var doc_name = "item-%d".printf(i);
  56. var doc_path = parent_path.append_child(doc_name);
  57. yield cleanup_path_async(doc_path);
  58. var doc = yield parent_container.create_document_async(doc_name, "TestItem");
  59. yield doc.set_entity_property_async(
  60. "category",
  61. new Invercargill.NativeElement<string>(i % 5 == 0 ? "A" : "B")
  62. );
  63. yield doc.set_entity_property_async(
  64. "priority",
  65. new Invercargill.NativeElement<int>(i % 10)
  66. );
  67. yield doc.set_entity_property_async(
  68. "active",
  69. new Invercargill.NativeElement<bool?>(i % 2 == 0)
  70. );
  71. // Track for deferred cleanup
  72. _cleanup_tracker.add_document(doc_path.to_string());
  73. }
  74. // Test 1: Create category with simple predicate
  75. var category_path = parent_path.append_child("category-a");
  76. print(" Testing create_category (%d iterations)...\n", quick_iterations);
  77. var create_op = new CreateCategoryOp(this, parent_container, category_path, "category-a", "TestItem", "category == \"A\"");
  78. var create_result = yield measure_async("create_category", quick_iterations, create_op);
  79. results.add(name, create_result);
  80. // Test 2: Get category members
  81. print(" Testing get_members (%d iterations)...\n", iterations);
  82. var get_op = new GetCategoryMembersOp(_engine, category_path);
  83. var get_result = yield measure_async("get_members", iterations, get_op);
  84. results.add(name, get_result);
  85. // Test 3: Create category with complex predicate
  86. var complex_category_path = parent_path.append_child("complex-category");
  87. print(" Testing create_category_complex (%d iterations)...\n", quick_iterations);
  88. var complex_create_op = new CreateCategoryOp(this, parent_container, complex_category_path, "complex-category", "TestItem", "category == \"A\" && priority > 5");
  89. var complex_create_result = yield measure_async("create_category_complex", quick_iterations, complex_create_op);
  90. results.add(name, complex_create_result);
  91. // Test 4: Get members from complex category
  92. print(" Testing get_members_complex (%d iterations)...\n", iterations);
  93. var complex_get_op = new GetCategoryMembersOp(_engine, complex_category_path);
  94. var complex_get_result = yield measure_async("get_members_complex", iterations, complex_get_op);
  95. results.add(name, complex_get_result);
  96. // Test 5: Create category with boolean predicate
  97. var bool_category_path = parent_path.append_child("active-category");
  98. print(" Testing create_category_bool (%d iterations)...\n", quick_iterations);
  99. var bool_create_op = new CreateCategoryOp(this, parent_container, bool_category_path, "active-category", "TestItem", "active");
  100. var bool_create_result = yield measure_async("create_category_bool", quick_iterations, bool_create_op);
  101. results.add(name, bool_create_result);
  102. // Test 6: Check membership
  103. print(" Testing contains_document (%d iterations)...\n", iterations);
  104. Core.Entity? cat_entity = yield _engine.get_entity_or_null_async(category_path);
  105. var category_entity = cat_entity as Entities.Category;
  106. var contains_op = new ContainsDocumentOp(category_entity, parent_path, test_doc_count);
  107. var contains_result = yield measure_async("contains_document", iterations, contains_op);
  108. results.add(name, contains_result);
  109. }
  110. }
  111. // Operation classes for CategoryBenchmark
  112. private class CreateCategoryOp : AsyncOperation {
  113. private CategoryBenchmark _benchmark;
  114. private Core.Entity _parent_container;
  115. private Core.EntityPath _category_path;
  116. private string _name;
  117. private string _entity_type;
  118. private string _predicate;
  119. public CreateCategoryOp(CategoryBenchmark benchmark, Core.Entity parent_container, Core.EntityPath category_path, string name, string entity_type, string predicate) {
  120. _benchmark = benchmark;
  121. _parent_container = parent_container;
  122. _category_path = category_path;
  123. _name = name;
  124. _entity_type = entity_type;
  125. _predicate = predicate;
  126. }
  127. public override async void execute_async() throws Error {
  128. yield _benchmark.cleanup_path_async(_category_path);
  129. yield _parent_container.create_category_async(_name, _entity_type, _predicate);
  130. // Track for deferred cleanup
  131. _benchmark._cleanup_tracker.add_category(_category_path.to_string());
  132. }
  133. }
  134. private class GetCategoryMembersOp : AsyncOperation {
  135. private Core.Engine _engine;
  136. private Core.EntityPath _category_path;
  137. public GetCategoryMembersOp(Core.Engine engine, Core.EntityPath category_path) {
  138. _engine = engine;
  139. _category_path = category_path;
  140. }
  141. public override async void execute_async() throws Error {
  142. var entity = yield _engine.get_entity_or_null_async(_category_path);
  143. if (entity != null) {
  144. var children = yield ((!) entity).get_children_async();
  145. // Force enumeration
  146. int count = 0;
  147. foreach (var child in children) {
  148. count++;
  149. }
  150. }
  151. }
  152. }
  153. private class ContainsDocumentOp : AsyncOperation {
  154. private Entities.Category? _category_entity;
  155. private Core.EntityPath _parent_path;
  156. private int _test_doc_count;
  157. public ContainsDocumentOp(Entities.Category? category_entity, Core.EntityPath parent_path, int test_doc_count) {
  158. _category_entity = category_entity;
  159. _parent_path = parent_path;
  160. _test_doc_count = test_doc_count;
  161. }
  162. public override async void execute_async() throws Error {
  163. if (_category_entity != null) {
  164. var test_path = _parent_path.append_child("item-%d".printf(iteration % _test_doc_count));
  165. // contains_document is synchronous (runs in DBM thread context)
  166. ((!) _category_entity).contains_document(test_path.to_string());
  167. }
  168. }
  169. }
  170. }