package main import "../../compiler/ast" import "../../compiler/checker" import "../../compiler/hir" import "../../compiler/lexer" import "../../compiler/parser" import "../../compiler/source" import "../../compiler/symbol" import "../../compiler/token" import "core:fmt" import "core:mem" import "core:strings" import "core:time" Metrics :: struct { token_count: int, unique_symbol_count: int, stored_symbol_bytes: int, diagnostic_count: int, } make_source :: proc(repetitions: int, allocator := context.allocator) -> string { builder := strings.builder_make(allocator) defer strings.builder_destroy(&builder) strings.write_string(&builder, "identity :: func(value int) int { return value }\n") strings.write_string(&builder, "main :: func() i32 {\n\tacc i32 = 0\n") for _ in 0 ..< repetitions { strings.write_string(&builder, "\t_ = identity(acc)\n\tacc = acc + 1\n") } strings.write_string(&builder, "\treturn acc\n}\n") return strings.clone(strings.to_string(builder), allocator) } run_pipeline :: proc(text: string, allocator := context.allocator) -> Metrics { source_file := source.Source{path="benchmark.bro", text=text} diagnostics := source.init_diagnostics(&source_file, allocator) defer source.destroy_diagnostics(&diagnostics) symbols := symbol.init_table(allocator) defer symbol.destroy_table(&symbols) stream := lexer.lex(&source_file, &diagnostics, &symbols, allocator) defer delete(stream.items) ast_module := parser.parse(&stream, &source_file, &diagnostics, allocator) defer ast.destroy_module(&ast_module) hir_module := checker.check(&ast_module, &diagnostics, &symbols, allocator) defer hir.destroy_module(&hir_module) return Metrics{ token_count=len(stream.items), unique_symbol_count=len(symbols.items), stored_symbol_bytes=symbols.stored_bytes, diagnostic_count=len(diagnostics.items), } } main :: proc() { text := make_source(5_000) defer delete(text) _ = run_pipeline(text) tracker: mem.Tracking_Allocator mem.tracking_allocator_init(&tracker, context.allocator) defer mem.tracking_allocator_destroy(&tracker) allocator := mem.tracking_allocator(&tracker) start := time.tick_now() metrics := run_pipeline(text, allocator) elapsed := time.tick_diff(start, time.tick_now()) fmt.printf("elapsed_ms: %.3f\n", time.duration_milliseconds(elapsed)) fmt.printf("peak_memory_bytes: %d\n", tracker.peak_memory_allocated) fmt.printf("allocation_count: %d\n", tracker.total_allocation_count) fmt.printf("token_count: %d\n", metrics.token_count) fmt.printf("token_size_bytes: %d\n", size_of(token.Token)) fmt.printf("unique_symbol_count: %d\n", metrics.unique_symbol_count) fmt.printf("stored_symbol_bytes: %d\n", metrics.stored_symbol_bytes) fmt.printf("diagnostic_count: %d\n", metrics.diagnostic_count) }