黑马程序员技术交流社区

标题: for 和 foreach 哪个效率高?foreach底层怎么实现的? [打印本页]

作者: .net_交流    时间: 2014-7-29 16:37
标题: for 和 foreach 哪个效率高?foreach底层怎么实现的?
本帖最后由 .net_交流 于 2014-7-29 18:37 编辑

for 和 foreach 哪个效率高?用法有什么区别?foreach内部底层怎么写的?
作者: 许庭洲    时间: 2014-7-29 16:43
本帖最后由 许庭洲 于 2014-7-29 16:54 编辑

1.foreach语句是在C#中新引入的,它表示收集一个集合中的各元素,并针对各个元素执行内嵌语句;
2.foreach语句格式:foreach(type identifier in expression) embedded-statement
3.其中类型(type )和标示符(identifier )用来声明循环变量,表达式(expression)对应集合。
4.每执行一次内嵌语句,循环变量就依次取集合中的一个元素代入其中。
5.for语句是C#中使用频率最高的循环语句。在事先知道循环次数的情况下,使用for语句是比较方便的。
6.for语句的格式为:for(initializer;condition;iterator) embedded-statement
7.其中,initializer,condition,iterator这三项都是可选项,initializer为循环控制变量做初始化,循环控制变量可以有一个或多个(用逗号隔开);condition为循环控制条件,也可以有一个或多个语句;iterator按规律改变循环控制变量的值。
8.如果可以用for遍历的,一般来说for语句效率高,用foreach的对象需要实现枚举接口,for就不用了。:
9. for 可以代替 foreach,但效率上讲后者高些,特别是集合对象。


作者: czwanglei    时间: 2014-7-29 17:38
当有人给你回复后,请及时把帖子编辑为提问结束,这样版主才给你加分。
作者: .net_交流    时间: 2014-7-29 18:42
许庭洲 发表于 2014-7-29 16:43
1.foreach语句是在C#中新引入的,它表示收集一个集合中的各元素,并针对各个元素执行内嵌语句;
2.foreach ...

8.如果可以用for遍历的,一般来说for语句效率高,用foreach的对象需要实现枚举接口,for就不用了。:
9. for 可以代替 foreach,但效率上讲后者高些,特别是集合对象。

最后这两句到底哪个效率高
作者: liangdmaster    时间: 2014-7-29 19:14
看完后觉得有点矛盾
作者: qsq0000hm    时间: 2014-7-29 19:52
键值对集合的遍历,for循环用不了了,只能使用foreach遍历
作者: 马振伟    时间: 2014-7-30 00:33
本帖最后由 马振伟 于 2014-7-30 13:12 编辑

这个最好自己测测就会知道的,用一个大数据的集合或者数组什么的,一个for一个foreach。可以发现for比foreach要快的,foreach遍历的时候,采用的是移动指针(MoveNext),一次移动的一个长度(相对于被遍历的对象长度来说),就这一点,速度是很快的,C#本身没法随便使用指针,for循环是每次根据当前索引相对于0索引的偏移去计算地址的偏移,然后根据首地址来计算实际的地址,单纯这样看,for循环肯定慢。但是foreach并不是直接遍历的源集合,而是将源集合的每个值拷贝到栈上(对于引用类型,拷贝的是对象的地址),我们在遍历的是这个拷贝(这就是为什么不能再foreach中更改源集合的理由,因为你拿到的已经不是源集合了),这个拷贝的时间导致foreach在速度上一般会输给普通的for循环
作者: 蜗牛阿布    时间: 2014-8-3 21:44
for与 foreach作用域不同,foreach作用于数组内部循环遍历的
作者: 麦田怪圈    时间: 2014-8-4 16:08
路过学习了!
作者: FrancisTan    时间: 2014-8-5 11:24
本帖最后由 FrancisTan 于 2014-8-5 11:28 编辑

纯讲效率的话,应该是for高,因为它是直接通过下标访问数组中的元素,而foreach在访问时会有一个对中间变量赋值的操作。foreach是通过指针偏移实现的,在最开始时,指针处于数组的-1位置(逻辑位置,实际就是在数组第一个元素前面),
很循环一次,指针就偏移一个单位,并将当前所指的元素赋值给中间变量,直到数组末尾。
所我用foreach是不能直接访问数组中的元素的,而且顺序永远都是一个挨着一个,不能改变。
而for循环则没有这些限制!个人喜欢在对数组只进行单纯的遍历,而不对数组元素进行操作的时候用foreach,比较方便!

作者: 130880130880    时间: 2014-8-6 18:45
foreach背后的原理                      1.自己写的类要被foreach 遍历就是要实现IEnumerable这个接口。          forrach背后的代码:          IEnumerator tor= lis.GetEnumerator();          while(tor.MoveNext())          {                  Console.Write(tor.Current);          }          2 GetEnumerator();这个方法 返回一个实现了IEnumerator接口对象          3.所以我们要实现IEnumerable这个接口中GetEnumerator()的话,就要写一个类来实现IEnumerator接口          并在GetEnumerator();方法中返回这个类的实例。          4.IEnumerator接口中定义一个Current只读属性 MoveNext方法  Reset()方法          5.MoveNext方法的作用 将指针向前移动一位 并判断当前位是否有元素 如果有返回true 没有就返回false          6.Current只读属性 得到当前指针指向的值          7.这两个方法都是在操作数组 而这个数组在我们的集合类中,所以我们要想办法将集合类中的数组传递到迭代器当前类中          8 迭代器对象在集合类中创建 所以可以通过构造函数让集合将他的数组传递给 迭代器,这个时候迭代器对象中应经有了数组的引用          9 实现MoveNext方法 声明index 变量 用来保存当前指针指向的数组的索引  默认-1          每调用一个这个方法 指针就向前移动一位 所以index++          判断数组[index]这个元素是否存在 index<count就存在          所以迭代器对象还需要知道元素的有效个数 通过构造函数传入          10 实现Current 只读属性 直接返回指针指向的数据 return arr[index]
作者: 官方    时间: 2014-9-13 19:39
不同实现用不同的方法吧




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2