在回答that SO question并被拒绝后,我想和你一起检查一下。
为了对我编写的代码的成本有一个草案,我倾向于以这种方式扩展操作。
您认为这是正确的假设/数量级/估计吗?
(当然,没有什么比真正的应用程序分析: - ))
编辑:根据您的回答和评论作为第一个结论,可以说我的数字1000 很大程度上高估了。答案 0 :(得分:5)
如果您要进行类似的大规模概括,您可能需要考虑使用硬数据进行备份。
我不怀疑你对大多数架构的相对效率是对的(我说的最简单,因为可能有一些奇怪的架构,我不知道)但是1000x
比例在没有证据的情况下是可疑的。
实际上,我并非 确定屏幕和磁盘I / O的相对效率,因为它可能会受到缓冲的影响。我经常发现,在将输出定向到磁盘文件时,向屏幕输出数千行的程序运行得更快。
例如,以下程序:
#include <stdio.h>
int main (void) {
int i;
for (i = 100000; i > 0; i--)
printf ("hello\n");
return 0;
}
运行:
pax$ time myprog
hello
hello
:
hello
real 0m12.861s
user 0m1.762s
sys 0m2.002s
pax$ time ./myprog >/tmp/qq
real 0m0.191s
user 0m0.160s
sys 0m0.050s
换句话说,该环境中的屏幕I / O(XP下的CygWin)持续时间长达67倍,CPU时间长达17倍(可能是因为所有Windows更新)。
答案 1 :(得分:3)
这是另一个快速而有趣的,如果不是科学可靠而且没有经过深思熟虑的测试:
char *memory;
NSLog (@"Start heap allocs");
for (int allocations = 0; allocations < 100000000; allocations++)
{
memory = malloc (1024);
memory[0] = 1;
memory[1023] = memory[0] + 1;
free(memory);
}
NSLog (@"End heap allocs");
NSLog (@"Start stack allocs");
for (int allocations = 0; allocations < 100000000; allocations++)
{
char memory2 [1024];
memory2[0] = 1;
memory2[1023] = memory2[0] + 1;
}
NSLog (@"End stack allocs");
和输出:
2011-02-12 11:46:54.078 Veg Met Chilli[4589:207] Start heap allocs
2011-02-12 11:47:06.759 Veg Met Chilli[4589:207] End heap allocs
2011-02-12 11:47:06.759 Veg Met Chilli[4589:207] Start stack allocs
2011-02-12 11:47:07.057 Veg Met Chilli[4589:207] End stack allocs
自己做数学,但这会使堆分配大约长42倍。我必须强调不要引用我的意思,肯定会有瑕疵!最值得注意的是将值实际分配给数据所需的相对时间。
编辑:新的测试数据。
所以现在我只是为每个堆调用一个方法并堆栈,而不是在循环中立即调用它们。结果:
2011-02-12 12:13:42.644 Veg Met Chilli[4678:207] Start heap allocs
2011-02-12 12:13:56.518 Veg Met Chilli[4678:207] End heap allocs
2011-02-12 12:13:56.519 Veg Met Chilli[4678:207] Start stack allocs
2011-02-12 12:13:57.842 Veg Met Chilli[4678:207] End stack allocs
这使得堆的分配只是堆栈分配的10倍。 为了使结果更准确,我还应该有一个没有内存分配的控制方法(但至少做了一些事情,以便不进行优化),并带走那段时间。我接下来会这样做......
编辑:对...... 现在代码看起来像这样:int control = 0;
NSLog (@"Start heap allocs");
for (int allocations = 0; allocations < 100000000; allocations++)
{
control += [self HeapAlloc];
}
NSLog (@"End heap allocs");
NSLog (@"Start stack allocs");
for (int allocations = 0; allocations < 100000000; allocations++)
{
control += [self StackAlloc];
}
NSLog (@"End stack allocs");
NSLog (@"Start no allocs");
for (int allocations = 0; allocations < 100000000; allocations++)
{
control += [self NoAlloc];
}
NSLog (@"End no allocs");
NSLog (@"%d", control);
-(int) HeapAlloc
{
int controlCalculation = rand();
char *memory = malloc (1024);
memory[0] = 1;
memory[1023] = memory[0] + 1;
free(memory);
return controlCalculation;
}
-(int) StackAlloc
{
int controlCalculation = rand();
char memory [1024];
memory[0] = 1;
memory[1023] = memory[0] + 1;
return controlCalculation;
}
-(int) NoAlloc
{
int controlCalculation = rand();
return controlCalculation;
}
结果是:
2011-02-12 12:31:32.676 Veg Met Chilli[4816:207] Start heap allocs
2011-02-12 12:31:47.306 Veg Met Chilli[4816:207] End heap allocs
2011-02-12 12:31:47.306 Veg Met Chilli[4816:207] Start stack allocs
2011-02-12 12:31:49.458 Veg Met Chilli[4816:207] End stack allocs
2011-02-12 12:31:49.459 Veg Met Chilli[4816:207] Start no allocs
2011-02-12 12:31:51.325 Veg Met Chilli[4816:207] End no allocs
所以控制时间是1.866秒。 从分配时间中取出: 堆叠0.286秒 堆12.764秒
因此,堆分配大约需要堆栈分配的45倍。
谢谢你,晚安! :)答案 2 :(得分:2)
第一点取决于很多事情,真的。如果你的内存不足,那么在堆上分配一些东西可能需要花费几分钟的时间。另一方面,堆栈可能已经在那时分配。
第二点取决于所使用的终端。输出到DOS屏幕是一回事,输出到Windows控制台窗口是另一回事,xterm也与它们完全不同。
至于第3点,我宁愿说它是现代硬盘的另一种方式。他们可以轻松处理每秒钟的megs,你怎么能想象在如此短的时间内输出那么多的终端呢?但是,对于少量数据,您可能是正确的,因为硬盘I / O可能需要一些时间来准备。