jakt icon indicating copy to clipboard operation
jakt copied to clipboard

Compile time performance roadmap

Open ilyapopov opened this issue 3 years ago • 12 comments

Jakt compiler is quite slow to compile. This slows down development of the language. Most of the time is spent in the Clang.

Currently on my machine:

$ time ./build/jakt selfhost/main.jakt > build/baseline.cpp
real	0m4.788s
$ time clang++ -std=c++20 -I runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals build/baseline.cpp
real	0m14.547s

Clang part

I have profiled this a little and saw some directions how compilation can be sped up:

  • [ ] A lot of time is spent in one type - Token. It is a Variant with ~100 alternatives, and is very slow to compile. Another one visible in the profile is CheckedExpression. While other variants in the code are not that prominent in the profile individually, they probably take quite some time cumulatively. This suggests that Variant is a good candidate for optimization.
  • [ ] Quite a lot of time spent compiling debug_description functions.
    • [ ] Consider not generating unused debug_decription fucntions
    • [x] debug_description still uses Variant::visit which is particularly slow to compile. Usage of visit has already been removed from other parts of generated code (matches), so it can be removed from here too. PR: https://github.com/SerenityOS/jakt/pull/1038 by @Hendiadyoin1 --- -1s build time (-8%)
    • [ ] Compilation of debug_description functions can be sped up by minimizing printing calls by merging them together.
  • [ ] There seems to be lot of redundant parentheses and curly braces. I don't know how much they affect compilation times, but it would be nice to remove them anyways
  • [ ] Split cpp code into multiple translation units (TUs) which can be compiled in parallel.
  • [ ] Find what compile flags can be used. Investigate
    • [x] -fno-exceptions https://github.com/SerenityOS/jakt/pull/1043 -2.7s (-23%)
    • -fno-rtti, -fno-unwind-tables did not make any measurable difference
  • [x] https://github.com/SerenityOS/jakt/pull/1042 by @Hendiadyoin1 -0.25s (-2%)

Jakt part

I have not investigated that yet

Appendix

Profiling was done with clang with command line:

time clang++ -std=c++20 -I runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -ftime-trace -c -o build/baseline.o build/baseline.cpp

This generates baseline.json in the build directory.

Profile is attached: baseline.zip you can inspect it using Speedscope, Perfetto, Chrome dev tools, etc.

ilyapopov avatar Aug 05 '22 17:08 ilyapopov

Replacing Variant with tagged unions improves the time by ~20-30%, see experiment here, a large part of the remaining template instantiation time is spent resolving the conversion of runtime-known indices to types and v./v. for is Variant.

alimpfard avatar Aug 05 '22 17:08 alimpfard

Point two will be fixed by #1038 If you link that in the bullet-point it will auto check it when the PR is merged

Hendiadyoin1 avatar Aug 06 '22 14:08 Hendiadyoin1

The index lookup can be done in the compiler instead of using Variant::has, that should speed things up a lot. note that the codegen is a bit confused as it tries to handle the case where the lhs of the is operator is not an enum, but that is never the case at this point in the code

maddanio avatar Aug 06 '22 14:08 maddanio

Turns out, -fno-exceptions cuts about 2.7s (23%) from build time!

hyperfine -r 5 "cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literalsi jakt.cpp" "cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -fno-exceptions jakt.cpp"
Benchmark 1: cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literalsi jakt.cpp
  Time (mean ± σ):     14.772 s ±  0.092 s    [User: 14.208 s, System: 0.552 s]
  Range (min … max):   14.666 s … 14.881 s    5 runs
 
Benchmark 2: cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -fno-exceptions jakt.cpp
  Time (mean ± σ):     11.989 s ±  0.069 s    [User: 11.431 s, System: 0.541 s]
  Range (min … max):   11.874 s … 12.059 s    5 runs
 
Summary
  'cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literals -fno-exceptions jakt.cpp' ran
    1.23 ± 0.01 times faster than 'cd jakt/build/ && clang++ -std=c++20 -I ../runtime/ -Wno-parentheses-equality -Wno-trigraphs -Wno-user-defined-literalsi jakt.cpp'

Just have to make sure this does not break anything.

ilyapopov avatar Aug 06 '22 15:08 ilyapopov

well, question is to we ever want to handle any c++ exceptions in jakt? i.e. in c++ extern blocks? if not then it is pretty sure ok

maddanio avatar Aug 06 '22 15:08 maddanio

We don't do c++ exceptions here We have our own Error for that, which is supposed to be cheaper

Hendiadyoin1 avatar Aug 06 '22 15:08 Hendiadyoin1

Excellent initiative! For the Jakt part, make sure you build jakt with optimizations (jakt -O). It should run significantly faster than 0m4.788s :^)

awesomekling avatar Aug 06 '22 16:08 awesomekling

I have also analyzed the build using excellent ClangBuildAnalyzer

For the current master, the report looks like:

View report
Analyzing build trace from '1'...
**** Time summary:
Compilation (2 times):
  Parsing (frontend):            7.4 s
  Codegen & opts (backend):      4.3 s

**** Files that took longest to parse (compiler frontend):
  5948 ms: build/CMakeFiles/jakt_stage1.dir//jakt_stage1_main.cpp.o
  1438 ms: build/CMakeFiles/jakt_stage1.dir//jakt_stage1_main.cpp.o

**** Files that took longest to codegen (compiler backend):
  4258 ms: build/CMakeFiles/jakt_stage1.dir//jakt_stage1_main.cpp.o

**** Templates that took longest to instantiate:
   131 ms: Jakt::Variant<Jakt::lexer::Token_Details::SingleQuotedString, Jakt::... (1 times, avg 131 ms)
   121 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 121 ms)
   120 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 120 ms)
   119 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 119 ms)
   118 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 118 ms)
   116 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 116 ms)
   115 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 115 ms)
   114 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 114 ms)
   113 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 113 ms)
   112 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 112 ms)
   110 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 110 ms)
   109 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 109 ms)
   108 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 108 ms)
   107 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 107 ms)
   106 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 106 ms)
   105 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 105 ms)
   103 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 103 ms)
   102 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 102 ms)
   101 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 101 ms)
   100 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 100 ms)
    99 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 99 ms)
    98 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 98 ms)
    97 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 97 ms)
    95 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 95 ms)
    94 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 94 ms)
    93 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 93 ms)
    92 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 92 ms)
    91 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 91 ms)
    90 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 90 ms)
    88 ms: Jakt::Detail::VisitImpl<unsigned char, Jakt::lexer::Token_Details::S... (1 times, avg 88 ms)

**** Template sets that took longest to instantiate:
   951 ms: Jakt::Variant<$>::can_contain<$> (305 times, avg 3 ms)
   927 ms: Jakt::Variant<$>::index_of<$> (293 times, avg 3 ms)
   884 ms: Jakt::Detail::index_of<$> (283 times, avg 3 ms)
   621 ms: JaktInternal::ExplicitValueOrControlFlow<$>::ExplicitValueOrControlF... (315 times, avg 1 ms)
   373 ms: Jakt::Variant<$> (349 times, avg 1 ms)
   366 ms: Jakt::Detail::VariantConstructors<$>::VariantConstructors (424 times, avg 0 ms)
   316 ms: JaktInternal::Array<$>::create_with (53 times, avg 5 ms)
   272 ms: Jakt::Variant<$>::visit<$> (39 times, avg 6 ms)
   249 ms: Jakt::ErrorOr<$> (222 times, avg 1 ms)
   227 ms: JaktInternal::Array<$>::create_empty (56 times, avg 4 ms)
   226 ms: Jakt::Detail::VisitImpl<$>::visit<$> (39 times, avg 5 ms)
   213 ms: Jakt::Detail::VisitImpl<$>::visit_impl<$> (27 times, avg 7 ms)
   149 ms: JaktInternal::ExplicitValueOrControlFlow<$> (105 times, avg 1 ms)
   139 ms: Jakt::adopt_nonnull_ref_or_enomem<$> (78 times, avg 1 ms)
   126 ms: Jakt::StringBuilder::appendff<$> (87 times, avg 1 ms)
   122 ms: Jakt::Variant<$>::Variant (42 times, avg 2 ms)
   114 ms: Jakt::VariadicFormatParams<$>::VariadicFormatParams (88 times, avg 1 ms)
    97 ms: Jakt::Variant<$>::set<$> (29 times, avg 3 ms)
    96 ms: JaktInternal::Dictionary<$>::create_with_entries (12 times, avg 8 ms)
    94 ms: Jakt::Formatter<$>::format (67 times, avg 1 ms)
    91 ms: Jakt::__format_value<$> (69 times, avg 1 ms)
    83 ms: Jakt::Detail::VariantConstructors<$> (47 times, avg 1 ms)
    68 ms: JaktInternal::Dictionary<$>::set (12 times, avg 5 ms)
    67 ms: Jakt::HashMap<$>::set (12 times, avg 5 ms)
    66 ms: Jakt::HashTable<$>::try_set<$> (13 times, avg 5 ms)
    61 ms: Jakt::Detail::Variant<$>::move_ (18 times, avg 3 ms)
    56 ms: JaktInternal::Dictionary<$>::create_empty (12 times, avg 4 ms)
    54 ms: JaktInternal::ExplicitValueOrControlFlow<$>::release_return (41 times, avg 1 ms)
    52 ms: Jakt::HashTable<$>::try_rehash (13 times, avg 4 ms)
    49 ms: Jakt::Variant<$>::~Variant (18 times, avg 2 ms)

**** Functions that took longest to compile:
    24 ms: Jakt::typechecker::Typechecker::typecheck_binary_operation(Jakt::Non... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
    13 ms: Jakt::typechecker::Typechecker::typecheck_expression(Jakt::NonnullRe... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
    12 ms: Jakt::codegen::CodeGenerator::codegen_expression(Jakt::NonnullRefPtr... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
    11 ms: Jakt::main(JaktInternal::Array<Jakt::String>) (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     9 ms: Jakt::typechecker::Typechecker::typecheck_enum(Jakt::parser::ParsedR... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     9 ms: Jakt::typechecker::Typechecker::typecheck_typename(Jakt::NonnullRefP... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     8 ms: Jakt::typechecker::Typechecker::typecheck_call(Jakt::parser::ParsedC... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     8 ms: Jakt::ide::get_type_signature(Jakt::NonnullRefPtr<Jakt::typechecker:... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     7 ms: Jakt::parser::Parser::parse_statement(bool)::$_38::operator()() const (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     7 ms: Jakt::ide::find_span_in_expression(Jakt::NonnullRefPtr<Jakt::typeche... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     7 ms: Jakt::typechecker::Typechecker::typecheck_struct_predecl(Jakt::parse... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     6 ms: Jakt::typechecker::CheckedProgram::type_name(Jakt::typechecker::Type... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     6 ms: Jakt::parser::Parser::parse_operand_base()::$_40::operator()() const (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     6 ms: Jakt::codegen::CodeGenerator::codegen_statement(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     5 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     5 ms: Jakt::typechecker::Typechecker::typecheck_enum_predecl(Jakt::parser:... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     5 ms: Jakt::typechecker::Typechecker::check_types_for_compat(Jakt::typeche... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     5 ms: Jakt::typechecker::Typechecker::typecheck_var_decl(Jakt::parser::Par... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::codegen::CodeGenerator::codegen_namespace(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::codegen::CodeGenerator::codegen_call(Jakt::typechecker::Checke... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::ide::completions_for_type_id(Jakt::NonnullRefPtr<Jakt::typeche... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::codegen::CodeGenerator::codegen_enum(Jakt::typechecker::Checke... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::typechecker::Typechecker::typecheck_function_predecl(Jakt::par... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::parser::Parser::parse_operand_postfix_operator(Jakt::utility::... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     4 ms: Jakt::ide::find_span_in_statement(Jakt::NonnullRefPtr<Jakt::typechec... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     3 ms: Jakt::Formatter<JaktInternal::Array<Jakt::parser::ParsedRecord>, voi... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     3 ms: Jakt::typechecker::CheckedFunction::debug_description() const (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)
     3 ms: Jakt::typechecker::Typechecker::substitute_typevars_in_type_helper(J... (/home/ilya/devel/external/jakt/build/jakt_stage1_main.cpp)

**** Function sets that took longest to compile / optimize:
    45 ms: Jakt::Formatter<$>::format(Jakt::FormatBuilder&, JaktInternal::Array... (50 times, avg 0 ms)
    24 ms: Jakt::typechecker::Typechecker::typecheck_binary_operation(Jakt::Non... (1 times, avg 24 ms)
    13 ms: Jakt::typechecker::Typechecker::typecheck_expression(Jakt::NonnullRe... (1 times, avg 13 ms)
    12 ms: Jakt::codegen::CodeGenerator::codegen_expression(Jakt::NonnullRefPtr... (1 times, avg 12 ms)
    11 ms: Jakt::main(JaktInternal::Array<$>) (1 times, avg 11 ms)
     9 ms: Jakt::Formatter<$>::format(Jakt::FormatBuilder&, JaktInternal::Dicti... (8 times, avg 1 ms)
     9 ms: Jakt::typechecker::Typechecker::typecheck_typename(Jakt::NonnullRefP... (1 times, avg 9 ms)
     8 ms: Jakt::typechecker::Typechecker::typecheck_call(Jakt::parser::ParsedC... (1 times, avg 8 ms)
     8 ms: Jakt::ide::get_type_signature(Jakt::NonnullRefPtr<Jakt::typechecker:... (1 times, avg 8 ms)
     7 ms: Jakt::ide::find_span_in_expression(Jakt::NonnullRefPtr<Jakt::typeche... (1 times, avg 7 ms)
     6 ms: Jakt::codegen::CodeGenerator::codegen_statement(Jakt::NonnullRefPtr<... (1 times, avg 6 ms)
     5 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 5 ms)
     5 ms: Jakt::typechecker::Typechecker::check_types_for_compat(Jakt::typeche... (1 times, avg 5 ms)
     5 ms: Jakt::typechecker::Typechecker::typecheck_var_decl(Jakt::parser::Par... (1 times, avg 5 ms)
     4 ms: Jakt::codegen::CodeGenerator::codegen_namespace(Jakt::NonnullRefPtr<... (1 times, avg 4 ms)
     4 ms: Jakt::ide::completions_for_type_id(Jakt::NonnullRefPtr<Jakt::typeche... (1 times, avg 4 ms)
     4 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 4 ms)
     4 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 4 ms)
     4 ms: Jakt::typechecker::Typechecker::typecheck_function_predecl(Jakt::par... (1 times, avg 4 ms)
     4 ms: Jakt::parser::Parser::parse_operand_postfix_operator(Jakt::utility::... (1 times, avg 4 ms)
     4 ms: Jakt::ide::find_span_in_statement(Jakt::NonnullRefPtr<Jakt::typechec... (1 times, avg 4 ms)
     3 ms: Jakt::Formatter<$>::~Formatter() (1 times, avg 3 ms)
     3 ms: Jakt::typechecker::Typechecker::substitute_typevars_in_type_helper(J... (1 times, avg 3 ms)
     3 ms: Jakt::parser::parsed_expression_equals(Jakt::NonnullRefPtr<Jakt::par... (1 times, avg 3 ms)
     3 ms: Jakt::Formatter<$>::format(Jakt::FormatBuilder&, Jakt::Tuple<$> cons... (5 times, avg 0 ms)
     3 ms: Jakt::typechecker::Typechecker::typecheck_for(Jakt::String, Jakt::ut... (1 times, avg 3 ms)
     3 ms: Jakt::typechecker::Typechecker::typecheck_statement(Jakt::NonnullRef... (1 times, avg 3 ms)
     3 ms: Jakt::typechecker::Typechecker::typecheck_array(Jakt::typechecker::S... (1 times, avg 3 ms)
     3 ms: Jakt::typechecker::Typechecker::typecheck_dictionary(JaktInternal::A... (1 times, avg 3 ms)
     3 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 3 ms)

*** Expensive headers:
175 ms: /home/ilya/devel/external/jakt/runtime/lib.h (included 1 times, avg 175 ms), included via:
  jakt_stage1_main.cpp.o  (175 ms)

  done in 0.0s.

A lot of time is taken by visit. After #1038, the report looks like

View report
../ClangBuildAnalyzer/build/ClangBuildAnalyzer --analyze 1
Analyzing build trace from '1'...
**** Time summary:
Compilation (2 times):
  Parsing (frontend):            7.0 s
  Codegen & opts (backend):      6.4 s

**** Files that took longest to parse (compiler frontend):
  5613 ms: build/CMakeFiles/jakt_stage1.dir//jakt_stage1_main.cpp.o
  1412 ms: build/CMakeFiles/jakt_stage1.dir//jakt_stage1_main.cpp.o

**** Files that took longest to codegen (compiler backend):
  6376 ms: build/CMakeFiles/jakt_stage1.dir//jakt_stage1_main.cpp.o

**** Templates that took longest to instantiate:
    51 ms: Jakt::Variant<Jakt::lexer::Token_Details::SingleQuotedString, Jakt::... (2 times, avg 25 ms)
    48 ms: JaktInternal::ExplicitValueOrControlFlow<Jakt::lexer::Token, Jakt::E... (1 times, avg 48 ms)
    45 ms: Jakt::Detail::VariantConstructors<JaktInternal::ExplicitValue<Jakt::... (1 times, avg 45 ms)
    42 ms: Jakt::Variant<Jakt::ErrorOr<Jakt::lexer::Token>, JaktInternal::Expli... (1 times, avg 42 ms)
    28 ms: Jakt::Detail::Variant<unsigned char, '\x00', Jakt::lexer::Token_Deta... (1 times, avg 28 ms)
    28 ms: Jakt::Detail::Variant<unsigned char, '\x01', Jakt::lexer::Token_Deta... (1 times, avg 28 ms)
    27 ms: Jakt::Detail::Variant<unsigned char, '\x02', Jakt::lexer::Token_Deta... (1 times, avg 27 ms)
    27 ms: Jakt::Detail::Variant<unsigned char, '\x03', Jakt::lexer::Token_Deta... (1 times, avg 27 ms)
    27 ms: Jakt::Detail::Variant<unsigned char, '\x04', Jakt::lexer::Token_Deta... (1 times, avg 27 ms)
    26 ms: Jakt::Detail::Variant<unsigned char, '\x05', Jakt::lexer::Token_Deta... (1 times, avg 26 ms)
    26 ms: Jakt::Detail::Variant<unsigned char, '\x06', Jakt::lexer::Token_Deta... (1 times, avg 26 ms)
    25 ms: Jakt::Detail::Variant<unsigned char, '\a', Jakt::lexer::Token_Detail... (1 times, avg 25 ms)
    25 ms: Jakt::Detail::Variant<unsigned char, '\b', Jakt::lexer::Token_Detail... (1 times, avg 25 ms)
    25 ms: Jakt::Detail::Variant<unsigned char, '\t', Jakt::lexer::Token_Detail... (1 times, avg 25 ms)
    24 ms: Jakt::Detail::Variant<unsigned char, '\n', Jakt::lexer::Token_Detail... (1 times, avg 24 ms)
    24 ms: Jakt::Detail::Variant<unsigned char, '\v', Jakt::lexer::Token_Detail... (1 times, avg 24 ms)
    24 ms: Jakt::Variant<Jakt::lexer::Token_Details::SingleQuotedString, Jakt::... (1 times, avg 24 ms)
    24 ms: Jakt::Detail::Variant<unsigned char, '\f', Jakt::lexer::Token_Detail... (1 times, avg 24 ms)
    23 ms: Jakt::Detail::Variant<unsigned char, '\r', Jakt::lexer::Token_Detail... (1 times, avg 23 ms)
    23 ms: Jakt::Detail::Variant<unsigned char, '\x0e', Jakt::lexer::Token_Deta... (1 times, avg 23 ms)
    23 ms: Jakt::Detail::Variant<unsigned char, '\x0f', Jakt::lexer::Token_Deta... (1 times, avg 23 ms)
    23 ms: Jakt::Detail::Variant<unsigned char, '\x10', Jakt::lexer::Token_Deta... (1 times, avg 23 ms)
    22 ms: Jakt::Detail::Variant<unsigned char, '\x11', Jakt::lexer::Token_Deta... (1 times, avg 22 ms)
    22 ms: Jakt::Detail::Variant<unsigned char, '\x12', Jakt::lexer::Token_Deta... (1 times, avg 22 ms)
    22 ms: Jakt::Detail::Variant<unsigned char, '\x13', Jakt::lexer::Token_Deta... (1 times, avg 22 ms)
    21 ms: Jakt::Detail::Variant<unsigned char, '\x14', Jakt::lexer::Token_Deta... (1 times, avg 21 ms)
    21 ms: Jakt::Detail::Variant<unsigned char, '\x15', Jakt::lexer::Token_Deta... (1 times, avg 21 ms)
    21 ms: Jakt::Detail::Variant<unsigned char, '\x16', Jakt::lexer::Token_Deta... (1 times, avg 21 ms)
    20 ms: Jakt::Detail::Variant<unsigned char, '\x17', Jakt::lexer::Token_Deta... (1 times, avg 20 ms)
    20 ms: Jakt::Detail::Variant<unsigned char, '\x18', Jakt::lexer::Token_Deta... (1 times, avg 20 ms)

**** Template sets that took longest to instantiate:
   930 ms: Jakt::Variant<$>::can_contain<$> (302 times, avg 3 ms)
   910 ms: Jakt::Variant<$>::index_of<$> (296 times, avg 3 ms)
   875 ms: Jakt::Detail::index_of<$> (284 times, avg 3 ms)
   619 ms: JaktInternal::ExplicitValueOrControlFlow<$>::ExplicitValueOrControlF... (315 times, avg 1 ms)
   386 ms: Jakt::Detail::VariantConstructors<$>::VariantConstructors (450 times, avg 0 ms)
   366 ms: Jakt::Variant<$> (327 times, avg 1 ms)
   311 ms: JaktInternal::Array<$>::create_with (53 times, avg 5 ms)
   250 ms: Jakt::ErrorOr<$> (222 times, avg 1 ms)
   223 ms: JaktInternal::Array<$>::create_empty (56 times, avg 3 ms)
   148 ms: JaktInternal::ExplicitValueOrControlFlow<$> (105 times, avg 1 ms)
   135 ms: Jakt::StringBuilder::appendff<$> (85 times, avg 1 ms)
   133 ms: Jakt::adopt_nonnull_ref_or_enomem<$> (78 times, avg 1 ms)
   128 ms: Jakt::Variant<$>::Variant (44 times, avg 2 ms)
   123 ms: Jakt::VariadicFormatParams<$>::VariadicFormatParams (88 times, avg 1 ms)
   100 ms: Jakt::Formatter<$>::format (67 times, avg 1 ms)
   100 ms: Jakt::__format_value<$> (70 times, avg 1 ms)
    96 ms: Jakt::Variant<$>::set<$> (29 times, avg 3 ms)
    88 ms: JaktInternal::Dictionary<$>::create_with_entries (12 times, avg 7 ms)
    84 ms: Jakt::Detail::VariantConstructors<$> (48 times, avg 1 ms)
    69 ms: JaktInternal::Dictionary<$>::set (12 times, avg 5 ms)
    68 ms: Jakt::HashMap<$>::set (12 times, avg 5 ms)
    67 ms: Jakt::HashTable<$>::try_set<$> (13 times, avg 5 ms)
    61 ms: Jakt::Detail::Variant<$>::move_ (18 times, avg 3 ms)
    52 ms: Jakt::HashTable<$>::try_rehash (13 times, avg 4 ms)
    52 ms: JaktInternal::ExplicitValueOrControlFlow<$>::release_return (40 times, avg 1 ms)
    50 ms: Jakt::Detail::Variant<$>::copy_ (19 times, avg 2 ms)
    49 ms: Jakt::HashTable<$>::try_lookup_for_writing (13 times, avg 3 ms)
    48 ms: JaktInternal::Dictionary<$>::create_empty (12 times, avg 4 ms)
    47 ms: Jakt::Variant<$>::~Variant (16 times, avg 2 ms)
    45 ms: Jakt::Detail::Variant<$>::delete_ (15 times, avg 3 ms)

**** Functions that took longest to compile:
   100 ms: Jakt::typechecker::CheckedExpression::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    75 ms: Jakt::parser::ParsedExpression::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    74 ms: Jakt::typechecker::Typechecker::typecheck_binary_operation(Jakt::Non... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    69 ms: Jakt::lexer::Token::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    47 ms: Jakt::typechecker::Typechecker::typecheck_expression(Jakt::NonnullRe... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    43 ms: Jakt::parser::ParsedStatement::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    40 ms: Jakt::codegen::CodeGenerator::codegen_expression(Jakt::NonnullRefPtr... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    36 ms: Jakt::main(JaktInternal::Array<Jakt::String>) (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    33 ms: Jakt::typechecker::CheckedStatement::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    31 ms: Jakt::parser::ParsedType::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    28 ms: Jakt::typechecker::Typechecker::typecheck_enum(Jakt::parser::ParsedR... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    28 ms: Jakt::typechecker::Typechecker::typecheck_typename(Jakt::NonnullRefP... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    27 ms: Jakt::ide::get_type_signature(Jakt::NonnullRefPtr<Jakt::typechecker:... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    26 ms: Jakt::typechecker::Typechecker::typecheck_call(Jakt::parser::ParsedC... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    22 ms: Jakt::parser::Parser::parse_statement(bool)::$_38::operator()() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    22 ms: Jakt::ide::find_span_in_expression(Jakt::NonnullRefPtr<Jakt::typeche... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    21 ms: Jakt::typechecker::Typechecker::typecheck_struct_predecl(Jakt::parse... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    21 ms: Jakt::codegen::CodeGenerator::codegen_statement(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    21 ms: Jakt::typechecker::CheckedProgram::type_name(Jakt::typechecker::Type... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    20 ms: Jakt::parser::Parser::parse_operand_base()::$_40::operator()() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    17 ms: Jakt::typechecker::Typechecker::typecheck_var_decl(Jakt::parser::Par... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    16 ms: Jakt::typechecker::Typechecker::typecheck_enum_predecl(Jakt::parser:... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    15 ms: Jakt::typechecker::Typechecker::check_types_for_compat(Jakt::typeche... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    15 ms: Jakt::typechecker::Type::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    15 ms: Jakt::codegen::CodeGenerator::codegen_call(Jakt::typechecker::Checke... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    14 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    14 ms: Jakt::codegen::CodeGenerator::codegen_namespace(Jakt::NonnullRefPtr<... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    14 ms: Jakt::codegen::CodeGenerator::codegen_enum(Jakt::typechecker::Checke... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    13 ms: Jakt::ide::find_span_in_statement(Jakt::NonnullRefPtr<Jakt::typechec... (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)
    13 ms: Jakt::typechecker::CheckedEnumVariant::debug_description() const (/home/ilya/devel/external/jakt-pr1038/build/jakt_stage1_main.cpp)

**** Function sets that took longest to compile / optimize:
   110 ms: Jakt::Formatter<$>::format(Jakt::FormatBuilder&, JaktInternal::Array... (50 times, avg 2 ms)
    74 ms: Jakt::typechecker::Typechecker::typecheck_binary_operation(Jakt::Non... (1 times, avg 74 ms)
    52 ms: JaktInternal::Array<$>::create_with(std::initializer_list<$>) (56 times, avg 0 ms)
    47 ms: Jakt::typechecker::Typechecker::typecheck_expression(Jakt::NonnullRe... (1 times, avg 47 ms)
    40 ms: Jakt::codegen::CodeGenerator::codegen_expression(Jakt::NonnullRefPtr... (1 times, avg 40 ms)
    39 ms: JaktInternal::Array<$>::create_empty() (56 times, avg 0 ms)
    36 ms: Jakt::main(JaktInternal::Array<$>) (1 times, avg 36 ms)
    28 ms: Jakt::typechecker::Typechecker::typecheck_typename(Jakt::NonnullRefP... (1 times, avg 28 ms)
    27 ms: Jakt::ide::get_type_signature(Jakt::NonnullRefPtr<Jakt::typechecker:... (1 times, avg 27 ms)
    26 ms: Jakt::typechecker::Typechecker::typecheck_call(Jakt::parser::ParsedC... (1 times, avg 26 ms)
    22 ms: Jakt::ide::find_span_in_expression(Jakt::NonnullRefPtr<Jakt::typeche... (1 times, avg 22 ms)
    22 ms: Jakt::Formatter<$>::format(Jakt::FormatBuilder&, JaktInternal::Dicti... (8 times, avg 2 ms)
    21 ms: Jakt::codegen::CodeGenerator::codegen_statement(Jakt::NonnullRefPtr<... (1 times, avg 21 ms)
    17 ms: Jakt::typechecker::Typechecker::typecheck_var_decl(Jakt::parser::Par... (1 times, avg 17 ms)
    15 ms: Jakt::typechecker::Typechecker::check_types_for_compat(Jakt::typeche... (1 times, avg 15 ms)
    14 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 14 ms)
    14 ms: Jakt::codegen::CodeGenerator::codegen_namespace(Jakt::NonnullRefPtr<... (1 times, avg 14 ms)
    13 ms: Jakt::ide::find_span_in_statement(Jakt::NonnullRefPtr<Jakt::typechec... (1 times, avg 13 ms)
    13 ms: Jakt::ide::completions_for_type_id(Jakt::NonnullRefPtr<Jakt::typeche... (1 times, avg 13 ms)
    13 ms: Jakt::parser::Parser::parse_operand_postfix_operator(Jakt::utility::... (1 times, avg 13 ms)
    13 ms: Jakt::typechecker::Typechecker::typecheck_statement(Jakt::NonnullRef... (1 times, avg 13 ms)
    11 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 11 ms)
    11 ms: Jakt::typechecker::Typechecker::typecheck_dictionary(JaktInternal::A... (1 times, avg 11 ms)
    11 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 11 ms)
    11 ms: JaktInternal::Dictionary<$>::create_with_entries(std::initializer_li... (12 times, avg 0 ms)
    11 ms: Jakt::typechecker::Typechecker::typecheck_for(Jakt::String, Jakt::ut... (1 times, avg 11 ms)
    10 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 10 ms)
    10 ms: Jakt::typechecker::Typechecker::typecheck_match(Jakt::NonnullRefPtr<... (1 times, avg 10 ms)
    10 ms: Jakt::typechecker::Typechecker::substitute_typevars_in_type_helper(J... (1 times, avg 10 ms)
    10 ms: Jakt::typechecker::Typechecker::typecheck_function_predecl(Jakt::par... (1 times, avg 10 ms)

*** Expensive headers:
171 ms: /home/ilya/devel/external/jakt-pr1038/runtime/lib.h (included 1 times, avg 171 ms), included via:
  jakt_stage1_main.cpp.o  (171 ms)

  done in 0.0s.

ilyapopov avatar Aug 06 '22 17:08 ilyapopov

We don't do c++ exceptions here

We have our own Error for that, which is supposed to be cheaper

I understand that and am completely on your side. I am just saying disabling exceptions also means you cannot call throwing functions in extern c++ code, even if you directly surround them with a catch-all clause. It severely limits interoperability

maddanio avatar Aug 06 '22 19:08 maddanio

Inside the serenity eco system that won't be an issue, but since a) serenity does have ports and you may wanna interact with non serenity libraries from jakt and b) this repo is separate and thus possibly also intended for non serenity use i thought this maybe something to consider

maddanio avatar Aug 06 '22 19:08 maddanio

Serenity ports do not build with exceptions last I checked -- the Diablo port had to have them removed and replaced with assertions IIRC.

drunderscore avatar Aug 06 '22 19:08 drunderscore

Serenity ports can choose to use whatever exception settings they like -- just if they end up interacting with Serenity native libraries (LibGUI for example), and they throw an exception through our libraries, we make no promises about what exception safety guarantees happens there. The C library has none, like basically every platform, and the STL is always either libc++ or libstdc++. Normally GUI stuff is funneled through SDL2, which again, with a C API I would hope no one is passing callbacks that can throw an exception through SDL2 layers.

If someone really wants to call throwing C++ code from jakt... that seems out of scope for this performance issue anyway, and should be a different issue :^)

ADKaster avatar Aug 08 '22 00:08 ADKaster