1

I have profiled my Rust code and see one processor-intensive function that takes a large portion of the time. Since I cannot break the function into smaller parts, I hope I can see which line in the function takes what portion of time. Currently I have tried CLion's Rust profiler, but it does not have that feature.

It would be best if the tool runs on MacOS since I do not have a Windows/Linux machine (except for virtualization).

P.S. Visual studio seems to have this feature; but I am using Rust. https://learn.microsoft.com/en-us/visualstudio/profiling/how-to-collect-line-level-sampling-data?view=vs-2017 It has:

Line-level sampling is the ability of the profiler to determine where in the code of a processor-intensive function, such as a function that has high exclusive samples, the processor has to spend most of its time.

Thanks for any suggestions!


EDIT: With C++, I do see source code line level information. For example, the following toy shows that, the "for" loop takes most of the time within the big function. But I am using Rust...

enter image description here

ch271828n
  • 15,854
  • 5
  • 53
  • 88

2 Answers2

1

To get source code annotation in perf annotate or perf report you need to compile with debug=2 in your cargo toml. If you also want source annotations for standard library functions you additionally need to pass -Zbuild-std to cargo (requires nightly).

the8472
  • 40,999
  • 5
  • 70
  • 122
0

Once compiled, "lines" of Rust do not exist. The optimiser does its job by completely reorganising the code you wrote and finding the minimal machine code that behaves the same as what you intended.

Functions are often inlined, so even measuring the time spent in a function can give incorrect results - or else change the performance characteristics of your program if you prevent it from being inlined to do so.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
  • Sounds quite reasonable! But I was using [visual studio's line-level sampling](https://learn.microsoft.com/en-us/visualstudio/profiling/how-to-collect-line-level-sampling-data?view=vs-2017) previously and it seemed to work well. Why does VS provide this feature? Thanks! – ch271828n Oct 25 '21 at 12:41
  • In addition, looking at [this question](https://stackoverflow.com/questions/44865551/source-line-numbers-in-perf-call-graph), it seems that the traditional `perf` tool also supports generating the line number. Am I wrong about that? – ch271828n Oct 25 '21 at 12:43
  • 1
    Moreover, how should I optimize my function, if I only know it is 100 lines long and is running slow, but know nothing about *where* it is slow? Thanks! – ch271828n Oct 25 '21 at 12:44
  • syscalls, allocations, nested loops... It's pretty hard to give advice here that isn't extremely general, and it probably isn't the place for it. – Peter Hall Oct 25 '21 at 13:00
  • Thanks. But I see `perf` also provides this feature (see edited question). So I guess it is not that useless...? – ch271828n Oct 25 '21 at 13:11
  • 1
    @ch271828n The lines you see in these tools are guesses. They can help orient you, like breadcrumbs, but they are not line-by-line translations. Sometimes you'll even see the same line repeated multiple times, even though you only wrote that line once in your source, because of inlining or loop unrolling. At this level, you have to be comfortable with reading the assembly and figuring out how it maps back to source yourself. One thing to try is `#inline(never)` on functions, and then viewing their assembly. You wouldn't do this for real profiling, but it can give a sense of the translation. – GManNickG Oct 25 '21 at 22:24