代码:
string str =string.Empty;
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");结果:
用时:386毫秒
代码:
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");结果:
用时:431毫秒
代码:
for (int x = 0; x < 2; x++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
}结果:
用时:393毫秒
用时:393毫秒
代码:
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
}
}结果:
用时:431毫秒
用时:431毫秒
用时:431毫秒
用时:432毫秒
代码:
for (int xxx = 0; xxx < 2; xxx++)
{
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
}
}
}结果:
用时:389毫秒
用时:396毫秒
用时:392毫秒
用时:390毫秒
用时:389毫秒
用时:390毫秒
用时:389毫秒
用时:391毫秒
这个性能和循环数量好像无关,但和奇偶有关呀????这是为什么呀
你这个开销是多大你计算了没
是string和尸体stringbuilding的区别还是很大的
这句好性能,在加大试试
for (int xxx = 0; xxx < 2; xxx++)
{
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
}
}
}
你外面循环一次,里面 Stopwatch watch = new Stopwatch();从新创建一个对象,所以结果肯定很相近呀!
测试个大概。。那结果我已经反复运行过所以是准确的为什么for的层次是奇数次比偶数次效率要高?统计得出一亿次约40毫秒(431-3901)
为什么for的层次是奇数次比偶数次效率要高?统计得出一亿次约40毫秒(431-3901)
string str = "a"; str = "a"; 虽然没看懂楼主是什么意思——!
个人感觉
string驻留机制使相同的字符串不需要重新在堆上分配内存,
但是string str = "a"; 意味着每次在栈上都会重新分配一个值类型存储指向堆的引用。似乎会有性能影响
如果是值类型,就会有明显的性能区分,这个其实是另一个问题,这里顺便就带一下了就当for是个里没有内容的空循环吧我发现这里面如同X=y的三行代码和一行性能一样,超过三行,第四行开始每行一亿次增加约60毫秒
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
这两个for是偶数,
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
这三个for或一个是奇数呀
{
for (int x = 0; x < 2; x++)跟
for( int xx=0; xx<4; xx++)不是一回事(因为它是“偶”),但是 for (int xxx = 0; xxx < 2; xxx++)
{
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)跟
for( int xx=0; xx<8; xx++)
就是一回事了(因为它是“奇”),是吗?
眼睛看就是390 391 392呀。或者 431 432误差10的几乎没有。奇偶就是上面的意思用0个for就当是偶数吧呵呵。。用一层for就当是1是奇数,
电脑不要同时间运行其他程序,如果不在测试,cpu基本闲置我是单独一个一个测试的结果很稳定
代码:
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
int z = 0;
while (z++<10000*10000)
{
string str = "a";
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
}
}结果:
用时:376毫秒
用时:377毫秒
用时:380毫秒
用时:377毫秒代码:
for (int xxx = 0; xxx < 2; xxx++)
{
for (int xx = 0; xx < 2; xx++)
{
for (int x = 0; x < 2; x++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
int z = 0;
while (z++<10000*10000)
{
string str = "a";
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
}
}
}结果:
用时:303毫秒
用时:297毫秒
用时:297毫秒
用时:296毫秒
用时:296毫秒
用时:296毫秒
用时:296毫秒
用时:296毫秒
我把for换成了while以更好的说明问题,for的奇偶层次的时间间隔都是存在的另外介绍一下(同本帖问题无关):用while并在条件中直接++性能也比for好,如果在执行代码中++和for差不多
鼠标放上去会提示str已经赋值,但没有使用。
所以你把string str = "a";注释掉,时间也是这个时间。所以现在问题只是比较i累加的时间。
我想这个差异应该是编译器优化算法造成的吧,
比如循环层次多了,会把内层某个循环进行某种特殊处理(猜的)
具体数值会随cpu改变,但中间的误差都是存在的,绝非巧合里面的代码不要同时运行,按我的一段一段分别运行
我重复N次了cpu基本闲置,而且并不是只测试一次我进行过N次都是这个结果。。大家不信可以分别复制代码测试一下是否存在差距。。(不要一次运行,那也会计算奇偶的)
string str ="a"
或
string str =string.Empty;
str ="a"
这种情况是在编译阶段决定值的,"a"是放在字符串常量池的,运行时字符串是恒定的,运行时你循环多少次都是那点时间。
另外,考虑到咱们的操作系统是多任务的,这个本身也会受到一点点影响
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
外面那些循环都是浮云吧 你没发现统计这个循环的时候时间的确是不多 只是string str比直接str慢了一点 没什么问题吧
+1
对于前面两次循环的差别就是string的特性了,新赋值时,其时会先检查一下串流池中是否也分配该变量(存在引用)可以参考以下两个方法:
String.Intern 方法
String.IsInterned 方法 既然LZ是想测试for的嵌套层次影响的效率,那就得首先保证循环里面一模一样,以使干扰最小化
加一个断点 转到汇编 看看。。或者编译以后 看IL...
看底层。。能看出区别
我倒觉得多说情况下是编译器做了优化 甚至于是JIT将其实时转化为CPU指令的时候做了些变化
是呀。。我重复好几遍了。。这就相当于一个空循环,程序本身无任何意义,只为测试方法中含有奇偶不同层次的for时,性能之间会有10%差异并不是越多时间越久,而是同奇偶有关cpu闲置,确定无其他程序占用。反复运行N次。。结果很稳定。。就是有约10%的间隔谁能解释?
JIT优化
进程调度优先级
CPU Cache命中率
CPU指令流水线
……
毕竟你的前两个例子内层耗时运算不是一个方法。
用时:248毫秒
用时:249毫秒
用时:250毫秒
用时:248毫秒偶数次for循环
用时:253毫秒
用时:256毫秒
用时:256毫秒
用时:251毫秒
用时:254毫秒
用时:255毫秒
用时:257毫秒
用时:256毫秒Release版编译,结果如下:奇数次for循环
用时:207毫秒
用时:210毫秒
用时:210毫秒
用时:210毫秒偶数次for循环
用时:210毫秒
用时:208毫秒
用时:208毫秒
用时:208毫秒
用时:210毫秒
用时:212毫秒
用时:207毫秒
用时:209毫秒可以看到,release版二者没什么大的区别,各有快慢,应该和for循环的嵌套的奇偶性无关吧
另外,我给楼主的代码各增加了2层嵌套,结果和上面的也没什么大的差异至于Debug版,我想应该没什么参考价值,谁知道VC在debug时做了什么手脚啊
你那里看到你CPU闲置了?你是一万核CPU每个核都是3G HZ还是?
你CPU闲置你系统怎么在跑..你在运行程序的时候你鼠标为什么在动?
CPU在扯蛋吧?
人家提出有建设性的问题不管不问就跟人家纠结其他的..
编译器优化过你又知道?
你这个统计时间的本身就不准你有知道?
你的for循环被编译成什么样子你又知道.?
用时:376毫秒
用时:381毫秒
用时:377毫秒用时:451毫秒
用时:375毫秒
用时:379毫秒
用时:379毫秒用时:453毫秒
用时:378毫秒
用时:378毫秒
用时:378毫秒用时:455毫秒
用时:378毫秒
用时:381毫秒
用时:380毫秒用时:448毫秒
用时:379毫秒
用时:379毫秒
用时:377毫秒用时:452毫秒
用时:381毫秒
用时:377毫秒
用时:377毫秒用时:444毫秒
用时:381毫秒
用时:377毫秒
用时:379毫秒
我顶楼的结果是debug版的刚经79楼的网友提醒测试了Release版的,多次运行的结果如上(奇偶都没有顶楼的明显差距,所以不重复帖了),这个Release第一遍可能还要编译的原因耗时比较多,没有顶楼的debug版的结果一致性
watch.Start();
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
watch.Stop();
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");
你输出的信心所有都是这个执行等性能。无论你循环几次他的值肯定是相近的。主要还是看你的CPU处理能力。如果你项更明确他的性能问题,建议你把Stopwatch写在所有循环的外层看看。要不你这么循环测同一段代码根本没意义。跟尺子测量同一段距离。你看的数值也是有误差的。
for (int i = 0; i < 10000 * 10000; i += 1)
{
string str = "a"; ;
}
textBox1.Text += ("用时:" + watch.ElapsedMilliseconds.ToString() + "毫秒\r\n");类似这2行,垃圾、狗屎一样的写法,编译器,就不应该让其通过,直接掐死丫的 M¥真是太仁义了