Skip to content

Proposal: Support end-user profiling for zig that integrates with clang's time-trace feature #8953

Open

Description

@moosichu

With features like comptime, being able to trace the time the zig compiler spends compiling code can allow for compile-times to be dealt-with in a systematic way as projects grow with time.

Fortunately, clang already has support for this kind of feature with the -ftime-trace flag:

https://aras-p.info/blog/2019/01/16/time-trace-timeline-flame-chart-profiler-for-Clang/

So the proposal is:

Add a -ftime-trace flag (supported by zig&zig build) that will add flame-chart files to zig-out/time-tracefor each compilation unit generated. For C/C++ compilation units the existing-ftime-trace` flag can be used for clang, whilst the real work would be in providing similar support for zig code.

It's worth stressing that this is a feature for users of the compiler and not developers of the compiler. So the data gathered should be about informing the user which parts of their code-base are taking the most time to compile, so that can be actioned on a per-project basis.

As a first step a -ftime-trace flag could just enable clang's time-trace for C/C++ compilation units because that would already be a useful feature to have.

Activity

  1. added
    proposalThis issue suggests language modifications. If it also has the "accepted" label then it is planned.
    on Jun 1, 2021
  2. added this to the 0.9.0 milestone on Jun 1, 2021
  3. modified the milestones: 0.9.0, 1.0.0 on Nov 24, 2021
  4. matu3ba commented on Mar 15, 2022

    @matu3ba
    Contributor

    This is not very specific yet regarding the implementation complexity, maintenance and benefit of the implementation.
    For now, tracy is used for profiling as it is highly accurate https://github.com/wolfpld/tracy.

    Personally, I would expect from an implementation as goal to use the fastest perf Kernel/runtime interface, if available, and emit tracy format or another widely used format for visualization.

    1. In comparison, how complex would --profile be?
    2. Which advantage would it have over tracy?
    3. What is the performance cost users have to pay for? Do you have numbers to estimate this?
  5. leecannon commented on Mar 15, 2022

    @leecannon
    Contributor

    The problem with tracy as it is currently utilized in stage2 is it shows how much time is spent in zig compiler stack frames in a way that is detached from the code that is being compiled, which is useful for a developer of the zig compiler itself but it is not useful for end users of zig to determine the compile time cost of their own code.

    This proposal is for an output that is useful for end-users of the zig compiler not zig compiler developers. Excerpt from blog post linked in first comment:

    "Various compilers have various ways of reporting something, but most of their reports seem to be geared towards the compiler developers themselves. For them it’s important to know, for example, whether register allocator is the bottleneck; for me as a compiler user that is much less of an importance – I want to know whether I’m bottlenecked by preprocessor / includes (if so, which ones?), parsing (if so, which classes/functions/templates?), template instantiation (if so, which ones?), code generation, backend optimizations, or something else."

  6. matu3ba commented on Mar 15, 2022

    @matu3ba
    Contributor

    I want to know whether I’m bottlenecked by preprocessor / includes (if so, which ones?), parsing (if so, which classes/functions/templates?), template instantiation (if so, which ones?), code generation, backend optimizations, or something else."

    Ah. This depends on finishing stage2 to measure carefully the perf cost and insert trace points, because most time will be spend in Sema, MIR and (LLVM) codegen.

  7. moosichu commented on Mar 15, 2022

    @moosichu
    ContributorAuthor

    Yeah - that captures the problem well. The reason the specific solutin is proposed (generating chrome-compatile flame charts) as this is what clang and llvm already use. As an end-user on large project that wants to reduce overall compile times, I want to be able to hollistically analyse the compilation bottlenecks, which ideally means I should be able to see zig, clang & llvm in the same profiling results.

    I've used this recently on a real-world C++ project, and it's an invaluable tool to have. Not just for the the front-end either, but also seeing which functions are expensive to optimise in the back-end, as that can often be addressed as well.

    With zig I feel something like this is even more vital with the compile time compilation features, as I could easily see project compile times blow-up if a couple of compile-time functions push those quite hard - in ways that could be optimisable.

  8. moosichu commented on Mar 15, 2022

    @moosichu
    ContributorAuthor

    At this point I can only speak as someone who has needed to use such a feature on a large real-world C++ project, and would only consider switching to the zig compiler & using zig on projects of such a scope if the --profile flag was supporte & intergrated with the way clang & llvm already handle it.

    I would even happily work on this feature (at some point), but haven't thought about implementation details at all. I would use what clang & llvm do as a starting point to look at.

    I think it's pretty important that it can be agreed that a feature like this with the requirments outlined is near-essential to the long-term viability of zig though. Unless an alternative solution is proposed that services the same goals.

  9. moosichu commented on Apr 6, 2022

    @moosichu
    ContributorAuthor

    I've done a little bit more thinking on this, and I think I would be quite keen to tackle this once the stage 2 compiler has shipped and I have completed other work (anyone else is welcome to pick this up though). I think with any kind of time tracing implementation, clang intergration would be ideal, so that it "just works" for compiling both zig & c/c++.

    The PR for integrating this into clang is here: aras-p/llvm-project-20170507#2 as can be seen it is quite simple.

    One thing that might be important for zig specifically is giving users control over profiling comptime features/code as well. I can envisage situations where comptime stuff could start taking up a significant amount of compilation times, and you want want to profile specific components of that. Two builtin functions might be needed for this, such as @compTraceStart() and @compTraceEnd().

  10. modified the milestones: 1.0.0, 1.1.0 on Jul 25, 2023
  11. moosichu commented on Jul 27, 2023

    @moosichu
    ContributorAuthor

    https://github.com/moosichu/zig/tree/feature/time-trace

    Finally started work on this. Going all-in on making it a zig "thing".

    Thanks to the zig build system, I think we have some good opportunities to integrate the kind of features that tooling like this does also:
    https://github.com/aras-p/ClangBuildAnalyzer

    This is very experimental atm! I don't really know what I'm doing, but it's a fun little project and one that I hope is quite valuable.

    The goal is to have something at the end, that means that when you do, zig build -ftime-trace, makes it easy to identify what and why your builds are slow so you can address the source of that, comprehensively covering all sources used to build all your artifacts (including the build.zig itself! which is important because you could be doing heavy stuff in there that makes it take long to build).

  12. nektro commented on Jul 27, 2023

    @nektro
    Contributor

    would implementing something with our own api surface (eg #15483) be more in-line with #16270

  13. moosichu commented on Jul 28, 2023

    @moosichu
    ContributorAuthor

    So I think this is trying to solve a different problem to #15483, and is still in line with #16270 - and I think going to the problem as an end-user might help clarify the goals here.

    Ultimately, as a user of zig, I might one day type zig build and notice that it's taking a bit longer than I would ideally be happy with. So what I want to be able to do is type zig build -ftime-trace and have that tell me/point me in the direction of which parts of my project setup are taking up that time (hopefully in an actionable way). And that's fundementally the problem being solved.

    I think it's important to consider this from a migration persepctive as well - for those "maintaining it with zig". People with large existing C & C++ codebases that aren't going to be replaced anytime soon are a target audience for zig - so we can leverage the existing tools that clang (provides) for now in surfacing this information in a way which is compatible with exisiting workflows around this.

    Furthermore, as those projects start to incoroporate more zig, we will want zig code that is contributing to the overall build times to be surfaced as well - so sticking to the format that clang uses for this makes sense from that perspective. Although due to the structure of the zig compiler, I'm thinking hard about how to best generate actionable data. Comptime is goig to be a good thing to focus on for this: comptime is very powerful but as you can write arbitrary zig code and turing-complete programs, it faces the same problems as metadata template progamming does in C++. However it's also a lot simpler in that the code itself is easy to reason about - so being able to surface which comptime bits are sucking up time in your builds, how they are sucking up that time and letting zig users action that is going to be important (which is why explicit comptime profile markers are going to be valuable here I think).

    If zig then becomes a standalone C/C++ compiler that doesn't rely on clang - it can then use this system as well, and the transition should hopefully be fairly seamless.

    I also think there are some amazing opportunities to really improve over the status quo here as well due to the fact that zig build is the standard here. The only reason third-party tools like https://github.com/aras-p/ClangBuildAnalyzer have to exist is because clang doesn't know about the build system invoking it - but there's no reason zig build couldn't automatically do that for you as well - which is my current intention with this project.

    I hope that all makes sense?

  14. AeonianDusk commented on Feb 6, 2025

    @AeonianDusk

    I have a real-world use for this. I wrote a parser generator entirely with zig's comptime expressions. With it, I can supply a tuple which specifies a formal language, and it'll spit out a struct that can be used to parse that language. It gives great results, but it's way too slow. The problem is definitely with my code, but the generator is complicated enough that I don't want to find the slow part through trial-and-error. A good profiler would solve that problem.

  15. moosichu commented on Mar 14, 2025

    @moosichu
    ContributorAuthor

    Whilst I was very keen to work on this feature, and still think it would be a good one to have, life events means that the chance I will have to work on this anytime soon is very low. So this could be a fun issue for someone to work on! I did have local branch with some intial changes to support his, but it's probably horriblu out of date by now anyway 😅

  16. added
    enhancementSolving this issue will likely involve adding new logic or components to the codebase.
    and removed
    proposalThis issue suggests language modifications. If it also has the "accepted" label then it is planned.
    acceptedThis proposal is planned.
    on Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSolving this issue will likely involve adding new logic or components to the codebase.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions