我在C中编写了一些代码,我惊讶地发现它执行的时间比我预期的要长。我想知道哪些操作成本高昂以及如何摆脱它们。
我使用赋值语句,条件(嵌套),循环,函数调用和回调。
对常见的C性能缺陷有什么好的参考?
我可以使用一个好的剖析器吗?
谢谢大家
感谢您的所有投入。你是绝对正确的:它的算法可以减慢事情(大幅度)。虽然通过编码实践可以获得一点性能提升 - 我100%确信只有错误的算法才能大大减慢事情的速度。
事实上:我正在研究RB树并按升序插入节点。花了很多时间(和Binary Search Tree(Skewed)一样糟糕)。在寻求你的建议后,我检查了算法,我在平衡方面犯了一个错误,使树倾斜(倾斜)。我纠正了它。
再次感谢您的建议。
答案 0 :(得分:20)
您的性能问题可能与您实施的算法有关,而与您使用的操作有关。
发布代码可能很有用。告诉我们你正在尝试做什么,以及你正在使用什么算法也会有所帮助。事实上,你的问题没有为任何人提供足够的信息给你一个有用的答案。
其他人推荐gprof - 如果你对分析你的代码感兴趣,那么我是第二个。我之前也使用过VTune,并喜欢它。但首先要确保你理解你的代码及其作用,并且在处理你期望它处理的数据大小时,你实现的算法是时间有效的。
另外,使用C并不意味着您的代码会自动运行得更快。通常,I / O绑定代码看不到性能改进。 UI重代码可能无法从使用低级语言中受益。通常,C是一种更好的实现语言,您需要低级访问,与硬件或低级操作系统服务连接,或者如果您有非常具体和严格的性能要求,这些要求很难在高级别,垃圾收集语言中满足。或者如果您碰巧喜欢C,但这显然是一个主观问题。
答案 1 :(得分:3)
这是一个陈旧的主题。
分析是一种选择,但是如果你有一个调试器,那么有一些老式的技术效果会非常好:
如果不需要一整天,请将代码单步执行。我保证如果它正在做任何不需要的事情,你会得到一个很好的主意。
如果这需要太长时间,只需给它足够的数据,或让程序在顶层重复,这样它就可以运行很长时间,至少几秒钟。在它运行时,手动中断它并记录它正在做什么和为什么。这样做几次。保证,您将从单步执行中获得相同的洞察力。
不要做大多数人做的事。大多数人所做的是1)勇敢地谈论剖析,然后2)猜测问题是什么并解决这个问题。如果你正在寻找“快速操作”,你就错过了这一点。在你通过上述调查之一证明它是什么之前,你永远不会找到正确的东西。
答案 2 :(得分:2)
不要浪费时间试图找到“昂贵”的操作。当然,除了图书馆之外,C中几乎没有。
相反,请尝试估计执行代码的每个部分的次数。例如,假设您将文件的每一行与另一行的每一行进行比较。如果每个文件都有大约一百行,那么你将进行大约一万次比较。没什么好担心的......但是如果你从文件的开头选择每一行,你就会读到每一行50万次。现在这不好。你需要一些真正的随机访问方式来阅读每一行....或者,更好的是,阅读关于哈希
in“big O”表示法:如果O(n x m)
和O(n^2)
相似,则整套比较为n
,或大致为m
。但顺序阅读平均为O(n/2)
,因此在阅读时整个事情为O(n^3/2)
加上O(n^2)
进行比较。使用散列,它将是aO(2n)+bO(2n)+cO(n^2)
,或仅O(n^2)
优化算法,而不是代码。
答案 3 :(得分:1)
检查内存分配。和函数调用。如果您正在使用gcc,请使用-pg选项通过分析信息对其进行编译,并通过gprof运行它。 VS Team System版附带了自己的Profiler。所以,请你选择。
答案 4 :(得分:1)
这是不可能的。你所命名的元素都不是很慢,即使它们是,它也不会自动意味着整个程序会因为它们而变慢。
您最好在启用了性能分析的情况下运行代码,并查看哪些部分成本最高。 (这取决于你的平台你将如何实际做到这一点。)
有关MSVC的信息,请参阅this post或this blog entry about profiling under MSVS甚至this question, and particularly the AMD CodeAnalyst answer
答案 5 :(得分:0)
您是否可以访问GNU工具链?如果是这样,请查看“gprof”。它是一个探测器......有利于找到瓶颈。