xcode 如何显示在 Instruments Time Profiler 中调用函数的次数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7787428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to show the number of times functions are called in Instruments Time Profiler
提问by an0
I've tried every possible fields but can not find the number of times functions are called.
我已经尝试了所有可能的字段,但找不到调用函数的次数。
Besides, I don't get Self
and # Self
. What do these two numbers mean?
此外,我不明白Self
和# Self
。这两个数字是什么意思?
回答by Pat
There are several other ways to accomplish this. One is obviously to create a static hit counter and an NSLog that emits and increments a counter. This is intrusive though and I found a way to do this with lldb.
还有其他几种方法可以实现这一点。一个显然是创建一个静态命中计数器和一个发射和递增计数器的 NSLog。虽然这是侵入性的,但我找到了一种使用 lldb 做到这一点的方法。
- Set a breakpoint
- Execute the program until you hit the breakpoint the first time and note the breakpoint number on the right hand side of the line you hit (e.g. "Thread 1: breakpoint 7.1", note the 7.1)
- Context click on the breakpoint and choose "Edit Breakpoint"
- Leave condition blank and choose "Add Action"
- Choose "Debugger Command"
- In the command box, enter "breakpoint list 7.1" (using the breakpoint number for your breakpoint from step 2). I believe you can use "info break " if you are using gdb.
- Check Options "Automatically Continue after evaluating"
- Continue
- 设置断点
- 执行程序直到您第一次遇到断点并注意您遇到的行右侧的断点编号(例如“线程 1:断点 7.1”,注意 7.1)
- 上下文单击断点并选择“编辑断点”
- 将条件留空并选择“添加操作”
- 选择“调试器命令”
- 在命令框中,输入“断点列表 7.1”(使用步骤 2 中断点的断点编号)。如果您使用的是 gdb,我相信您可以使用“信息中断”。
- 选中“评估后自动继续”选项
- 继续
Now, instead of stopping, llvm will emit info about the breakpoint including the number of times it has been passed.
现在,llvm 不会停止,而是会发出有关断点的信息,包括它已通过的次数。
As for the discussion between Glenn and Mike on the previous answer, I'll describe a performance problem where function execution count was useful: I had a particular action in my app where performance degraded considerably with each execution of the action. The Instruments time profiler showed that each time the action was executed, a particular function was taking twice as long as the time before until quickly the app would hang if the action was performed repeatedly. With the count, I was able to determine that with each execution, the function was called twice as many times as it was during the previous execution. It was then pretty easy to look for the reason, which turned out to be that someone was re-registering for a notification in NotificationCenter on each event execution. This had the effect of doubling the number of response handler calls on each execution and thus doubling the "cost" of the function each time. Knowing that it was doubling because it was called twice as many times and not because the performance was just getting worse caused me to look at the calling sequence rather than for reasons the function itself could be degrading over time.
至于 Glenn 和 Mike 之间关于上一个答案的讨论,我将描述一个性能问题,其中函数执行计数很有用:我的应用程序中有一个特定的操作,每次执行该操作时性能都会显着下降。Instruments 时间分析器显示,每次执行操作时,特定功能所用的时间是之前的两倍,直到如果重复执行该操作,应用程序很快就会挂起。通过计数,我能够确定每次执行时,该函数被调用的次数是上次执行期间的两倍。然后很容易找到原因,结果是有人在每次事件执行时在 NotificationCenter 中重新注册通知。这会导致每次执行时响应处理程序调用的次数加倍,从而使每次函数的“成本”加倍。知道它加倍是因为它被调用了两倍,而不是因为性能越来越差,这让我查看调用序列,而不是因为函数本身可能会随着时间的推移而降级。
回答by waggles
It seems you cannot use Time Profiler for counting function calls. This questionseems to address potential methods for counting.
似乎您不能使用 Time Profiler 来计算函数调用。这个问题似乎解决了潜在的计数方法。
W/ respect to selfand #self:
W/尊重自我和#self:
Self
is "The number of times the symbol calls itself."according to the Apple Docson the Time Profiler.
Self
是“符号调用自身的次数”。根据Time Profiler 上的Apple Docs。
From the way the numbers look though, it seems self
is the summed duration of samples that had this symbol at the bottom of its stack trace. That would make:
但是,从数字的外观来看,似乎self
是在其堆栈跟踪底部具有此符号的样本的总持续时间。这将使:
# self
: the number of samples where this symbol was at the bottom of the stack trace% self
: the percent of self samples relative to total samples of currently displayed call tree- (eg -
#self
/total samples
).
- (eg -
# self
:此符号位于堆栈跟踪底部的样本数% self
:自身样本相对于当前显示的调用树的总样本的百分比- (例如 -
#self
/total samples
)。
- (例如 -
So this wouldn't tell you how many times a method was called. But it would give you an idea how much time is spent in a method or lower in the call tree.
所以这不会告诉你一个方法被调用了多少次。但它会让你知道在调用树中的方法或更低的方法中花费了多少时间。
NOTE: I too am unsure about the various 'self' meanings though. Would love to see someone answer this authoritatively. Arrived here searching for that...
注意:我也不确定各种“自我”的含义。很想看到有人权威地回答这个问题。来到这里寻找那个......
回答by David Dunham
While it's interesting, knowing the number of times called doesn't have anything to do with how much time is spent in them. Which is what Time Profiler is all about. In fact, since it does sampling, it cannot answer how many times.
虽然很有趣,但知道被调用的次数与在其中花费的时间没有任何关系。这就是 Time Profiler 的全部意义所在。其实,既然是做采样的,就不能回答多少次。
回答by Mike Dunlavey
IF your objective is to find out what you need to fix to make the program as fast as possible,
如果您的目标是找出需要修复的内容以尽快完成程序,
Number of calls and self time may be interesting but are irrelevant.
通话次数和自拍时间可能很有趣,但无关紧要。
Look at my answer to this question, in particular points 6 and 8.
看看我对这个问题的回答,特别是第 6 点和第 8 点。
EDIT: To clarify the point further, suppose the following is the timeline of execution of the program. Some of that time (in this case about 50%) is spent in an activity that can be removed, if you know what it is, such as needless buried I/O, excessive calls to new
, runaway notifications, or "insignificant" data validation. If a random-time sample is taken, it has a 50% chance of occurring in that activity, and an examination of the call stack and/or program variables shows that it is doing something that can be removed. Then, if 10 such samples are taken, the activity will be seen on roughly 5 of them, regardless of whether the activity occurs in a few large chunks of time, or many small ones. The activity may be a few lines of code in a function doing something unnecessary, or it may be something much more generalized. Regardless, you recognize it, fix it, and get roughly a factor of 2 speedup. Call counts and self time contribute nothing to this process.
编辑:为了进一步澄清这一点,假设以下是程序执行的时间表。一些时间(在这种情况下大约 50%)花在可以删除的活动上,如果你知道它是什么,比如不必要的埋藏 I/O、过度调用new
、失控通知或“无关紧要”的数据验证。如果采用随机时间样本,它有 50% 的机会发生在该活动中,并且对调用堆栈和/或程序变量的检查表明它正在做一些可以删除的事情。然后,如果采集了 10 个这样的样本,则将在其中大约 5 个样本上看到活动,无论活动是在几个大的时间段内发生,还是在许多小时间段内发生。活动可能是函数中的几行代码做一些不必要的事情,或者它可能是更通用的东西。无论如何,您识别它,修复它,并获得大约 2 倍的加速。呼叫计数和自拍时间对这个过程没有任何贡献。