| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- /**
- * PostIndexDocumentBenchmark - Benchmarks for Document operations with indexes present
- *
- * Measures performance of document creation, reading, and updating
- * when indexes, categories, and catalogues are present. This is slower
- * due to hooks being triggered on document operations.
- *
- * @version 0.2
- * @since 0.1
- */
- namespace Implexus.Tools.Perf {
- /**
- * Benchmark for Document entity operations with indexes present.
- *
- * This benchmark runs after the Index, Category, and Catalogue benchmarks
- * to measure the performance impact of having indexed entities present.
- *
- * Tests:
- * - create_document_small_indexed: Creating documents with few properties (with indexes)
- * - create_document_large_indexed: Creating documents with many properties (with indexes)
- * - get_document_indexed: Reading document properties (with indexes)
- * - update_document_indexed: Modifying document properties (with indexes)
- * - get_property_indexed: Getting a single property (with indexes)
- * - delete_document_indexed: Deleting documents (with indexes)
- */
- public class PostIndexDocumentBenchmark : Benchmark {
-
- /**
- * {@inheritDoc}
- */
- public override string name { get { return "PostIndexDocument"; } }
-
- /**
- * Creates a new PostIndexDocumentBenchmark.
- *
- * @param engine The engine to benchmark
- * @param config The benchmark configuration
- */
- public PostIndexDocumentBenchmark(Core.Engine engine, BenchmarkConfig config) {
- base(engine, config);
- }
-
- /**
- * {@inheritDoc}
- */
- public override async void run_async(Results results) throws Error {
- // Create parent container for post-index documents
- var parent_path = new Core.EntityPath("/perf-test/post-index-docs");
- yield ensure_container_async(new Core.EntityPath("/perf-test"), "perf-test");
- // Note: /perf-test is already tracked by previous benchmarks
-
- yield cleanup_path_async(parent_path);
-
- var root = yield _engine.get_root_async();
- var perf_test = yield root.get_child_async("perf-test");
- var parent_container = yield perf_test.create_container_async("post-index-docs");
- _cleanup_tracker.add_container(parent_path.to_string());
-
- int iterations = _config.iterations;
- int heavy_iterations = _config.heavy_iterations;
-
- // Test 1: Create documents with small properties (with indexes present)
- print(" Testing create_document_small_indexed (%d iterations)...\n", iterations);
- var create_small_op = new CreateSmallIndexedDocOp(this, parent_container, parent_path);
- var create_small = yield measure_async("create_document_small_indexed", iterations, create_small_op);
- results.add(name, create_small);
-
- // Test 2: Create documents with large properties (with indexes present)
- print(" Testing create_document_large_indexed (%d iterations)...\n", heavy_iterations);
- var create_large_op = new CreateLargeIndexedDocOp(this, parent_container, parent_path);
- var create_large = yield measure_async("create_document_large_indexed", heavy_iterations, create_large_op);
- results.add(name, create_large);
-
- // Test 3: Read documents (small, with indexes present)
- print(" Testing get_document_indexed (%d iterations)...\n", iterations);
- var read_op = new GetIndexedDocumentOp(_engine, parent_path, iterations);
- var read_result = yield measure_async("get_document_indexed", iterations, read_op);
- results.add(name, read_result);
-
- // Test 4: Update documents (with indexes present)
- print(" Testing update_document_indexed (%d iterations)...\n", iterations);
- var update_op = new UpdateIndexedDocumentOp(_engine, parent_path, iterations);
- var update_result = yield measure_async("update_document_indexed", iterations, update_op);
- results.add(name, update_result);
-
- // Test 5: Get property by name (with indexes present)
- print(" Testing get_property_indexed (%d iterations)...\n", iterations);
- var get_prop_op = new GetIndexedPropertyOp(_engine, parent_path, iterations);
- var get_prop_result = yield measure_async("get_property_indexed", iterations, get_prop_op);
- results.add(name, get_prop_result);
-
- // Test 6: Delete documents (with indexes present)
- print(" Testing delete_document_indexed (%d iterations)...\n", iterations);
- var delete_op = new DeleteIndexedDocumentOp(_engine, parent_path);
- var delete_result = yield measure_async("delete_document_indexed", iterations, delete_op);
- results.add(name, delete_result);
- }
- }
- // Operation classes for PostIndexDocumentBenchmark
- private class CreateSmallIndexedDocOp : AsyncOperation {
- private PostIndexDocumentBenchmark _benchmark;
- private Core.Entity _parent_container;
- private Core.EntityPath _parent_path;
-
- public CreateSmallIndexedDocOp(PostIndexDocumentBenchmark benchmark, Core.Entity parent_container, Core.EntityPath parent_path) {
- _benchmark = benchmark;
- _parent_container = parent_container;
- _parent_path = parent_path;
- }
-
- public override async void execute_async() throws Error {
- var doc_name = "post-doc-%d".printf(iteration);
- var doc_path = _parent_path.append_child(doc_name);
- yield _benchmark.cleanup_path_async(doc_path);
- var doc = yield _parent_container.create_document_async(doc_name, "User");
- yield doc.set_entity_property_async("name", new Invercargill.NativeElement<string>("post-user-%d".printf(iteration)));
- yield doc.set_entity_property_async("age", new Invercargill.NativeElement<int>(iteration));
- // Track for deferred cleanup
- _benchmark._cleanup_tracker.add_document(doc_path.to_string());
- }
- }
- private class CreateLargeIndexedDocOp : AsyncOperation {
- private PostIndexDocumentBenchmark _benchmark;
- private Core.Entity _parent_container;
- private Core.EntityPath _parent_path;
-
- public CreateLargeIndexedDocOp(PostIndexDocumentBenchmark benchmark, Core.Entity parent_container, Core.EntityPath parent_path) {
- _benchmark = benchmark;
- _parent_container = parent_container;
- _parent_path = parent_path;
- }
-
- public override async void execute_async() throws Error {
- var doc_name = "post-large-doc-%d".printf(iteration);
- var doc_path = _parent_path.append_child(doc_name);
- yield _benchmark.cleanup_path_async(doc_path);
- var doc = yield _parent_container.create_document_async(doc_name, "LargeDocument");
- // Add 50 properties
- for (int j = 0; j < 50; j++) {
- yield doc.set_entity_property_async(
- "field_%d".printf(j),
- new Invercargill.NativeElement<string>("post-value-%d-%d".printf(iteration, j))
- );
- }
- // Track for deferred cleanup
- _benchmark._cleanup_tracker.add_document(doc_path.to_string());
- }
- }
- private class GetIndexedDocumentOp : AsyncOperation {
- private Core.Engine _engine;
- private Core.EntityPath _parent_path;
- private int _iterations;
-
- public GetIndexedDocumentOp(Core.Engine engine, Core.EntityPath parent_path, int iterations) {
- _engine = engine;
- _parent_path = parent_path;
- _iterations = iterations;
- }
-
- public override async void execute_async() throws Error {
- var doc_name = "post-doc-%d".printf(iteration % _iterations);
- var path = _parent_path.append_child(doc_name);
- var entity = yield _engine.get_entity_or_null_async(path);
- if (entity != null) {
- // Access properties to force load
- var props = yield ((!) entity).get_properties_async();
- var name_prop = props.get("name");
- }
- }
- }
- private class UpdateIndexedDocumentOp : AsyncOperation {
- private Core.Engine _engine;
- private Core.EntityPath _parent_path;
- private int _iterations;
-
- public UpdateIndexedDocumentOp(Core.Engine engine, Core.EntityPath parent_path, int iterations) {
- _engine = engine;
- _parent_path = parent_path;
- _iterations = iterations;
- }
-
- public override async void execute_async() throws Error {
- var doc_name = "post-doc-%d".printf(iteration % _iterations);
- var path = _parent_path.append_child(doc_name);
- var entity = yield _engine.get_entity_or_null_async(path);
- if (entity != null) {
- yield ((!) entity).set_entity_property_async(
- "updated",
- new Invercargill.NativeElement<bool?>(true)
- );
- }
- }
- }
- private class GetIndexedPropertyOp : AsyncOperation {
- private Core.Engine _engine;
- private Core.EntityPath _parent_path;
- private int _iterations;
-
- public GetIndexedPropertyOp(Core.Engine engine, Core.EntityPath parent_path, int iterations) {
- _engine = engine;
- _parent_path = parent_path;
- _iterations = iterations;
- }
-
- public override async void execute_async() throws Error {
- var doc_name = "post-doc-%d".printf(iteration % _iterations);
- var path = _parent_path.append_child(doc_name);
- var entity = yield _engine.get_entity_or_null_async(path);
- if (entity != null) {
- var prop = yield ((!) entity).get_entity_property_async("name");
- }
- }
- }
- private class DeleteIndexedDocumentOp : AsyncOperation {
- private Core.Engine _engine;
- private Core.EntityPath _parent_path;
-
- public DeleteIndexedDocumentOp(Core.Engine engine, Core.EntityPath parent_path) {
- _engine = engine;
- _parent_path = parent_path;
- }
-
- public override async void execute_async() throws Error {
- var doc_name = "post-doc-%d".printf(iteration);
- var path = _parent_path.append_child(doc_name);
- var entity = yield _engine.get_entity_or_null_async(path);
- if (entity != null) {
- yield ((!) entity).delete_async();
- }
- }
- }
- }
|