C# 时间复杂度-这两种算法中哪一种更快?
说明C# 时间复杂度-这两种算法中哪一种更快?,c#,algorithm,performance,foreach,C#,Algorithm,Performance,Foreach,说明 foreach(User u in userList) { foreach(Order o in u.orders) { orderList.Add(o); foreach(Product p in o.products) { productList.Add(p); } } } foreach(User u in userList) { foreach(Order o in u.orders)
foreach(User u in userList) {
foreach(Order o in u.orders) {
orderList.Add(o);
foreach(Product p in o.products) {
productList.Add(p);
}
}
}
foreach(User u in userList) {
foreach(Order o in u.orders) {
orderList.Add(o);
}
}
foreach(Order o in orderList) {
foreach(Product p in o.products) {
productList.Add(p);
}
}
此程序的目标是从用户中填充订单列表
订单和每个订单的productList。(请忽略此伪C代码中可能出现的语法错误)
数据结构
class User {
List<Order> orders;
}
class Order {
List<Product> products;
}
class Product {
int price;
}
List<User> userList = GetUsersFromDB();
List<Order> orderList = new List<Order>();
List<Product> productList = new List<Product>();
第二版
foreach(User u in userList) {
foreach(Order o in u.orders) {
orderList.Add(o);
foreach(Product p in o.products) {
productList.Add(p);
}
}
}
foreach(User u in userList) {
foreach(Order o in u.orders) {
orderList.Add(o);
}
}
foreach(Order o in orderList) {
foreach(Product p in o.products) {
productList.Add(p);
}
}
我的想法
class User {
List<Order> orders;
}
class Order {
List<Product> products;
}
class Product {
int price;
}
List<User> userList = GetUsersFromDB();
List<Order> orderList = new List<Order>();
List<Product> productList = new List<Product>();
- 第一程序T(n)=O(n^3)
- 第二程序T(n)=O(n^2)+O(n^2)
概述 你对第二个案例的分析是错误的。由于第一个循环的每个内部内容在orderlist中都有一个条目,
foreach(orderlist中的Order o)
在n^2个项目上循环。话虽如此,有一个免责声明,n在这里不是很有意义,因为它代表多个事物
最好用u,o和p来代替
案例1
第一个显然是O(uop)
案例2
此案例有两组循环。第一对循环是O(uo)
,正如您所期望的那样
然后,第二对循环以uo
项的循环开始,然后是O(p)的内部循环,因此第二对循环是O(uop)
。总的来说,这使得其O(uo)+O(uop)
相当于O(uop)
,与案例1相同
从本质上讲,第二种情况只是稍微改变了一下,实际上根本没有改变基本算法
现实世界
一如既往,如果你真正关心的是现实世界的性能,而不仅仅是理论上的算法复杂性(这在查看特定情况时并不总是有用),那么请对你的两种技术的性能进行基准测试。概述 你对第二个案例的分析是错误的。由于第一个循环的每个内部内容在orderlist中都有一个条目,
foreach(orderlist中的Order o)
在n^2个项目上循环。话虽如此,有一个免责声明,n在这里不是很有意义,因为它代表多个事物
最好用u,o和p来代替
案例1
第一个显然是O(uop)
案例2
此案例有两组循环。第一对循环是O(uo)
,正如您所期望的那样
然后,第二对循环以uo
项的循环开始,然后是O(p)的内部循环,因此第二对循环是O(uop)
。总的来说,这使得其O(uo)+O(uop)
相当于O(uop)
,与案例1相同
从本质上讲,第二种情况只是稍微改变了一下,实际上根本没有改变基本算法
现实世界
一如既往,如果你真正关心的是真实世界的性能,而不仅仅是理论上的算法复杂性(这在查看具体案例时并不总是有用),那么请对你的两种技术的性能进行基准测试。你尝试过吗?n表示什么?添加操作是在固定时间内执行的吗?@YvesDaoust Im假设列表的长度。从技术上讲,它应该是
O(u*O*p)
@Mitchel0022:对不起,我是在问OP。作为一个完整的旁白,如果效率是游戏的名称,你最好为foreach
上的循环实现香草,因为foreach
将创建枚举数实例。一个小的开销,但仍然有…你试过了吗?n表示什么?添加操作是在固定时间内执行的吗?@YvesDaoust Im假设列表的长度。从技术上讲,它应该是O(u*O*p)
@Mitchel0022:对不起,我是在问OP。作为一个完整的旁白,如果效率是游戏的名称,你最好为foreach
上的循环实现香草,因为foreach
将创建枚举数实例。虽然开销很小,但是……第二种情况不是uo
+op
?@FatihAkici:第二种情况有两组循环。第一对循环是uo
,正如您所期望的那样。第二对遍历orderList,我们知道它包含uo
项,因此它实际上是uop
。因此,总体而言,它是uo+uop
,相当于uop
。我会看看能否在我的答案中更好地解释这一点。@FatihAkici:我已经更新了答案,希望能更清楚。如果您认为它还需要更多的工作,请告诉我。哦,最后一个循环是在orderList上迭代,而不是在orders上。我的错,谢谢你澄清CA+1on@法蒂哈奇:没问题。第一次读这个问题时我也被弄糊涂了——我觉得“这根本不是在做同样的事情!”:)第二个例子不是uo
+op
?@FatihAkici:第二个例子有两组循环。第一对循环是uo
,正如你所预料的那样。第二对遍历orderList,我们知道它包含uo
项,因此它实际上是uop
。因此,总体而言,它是uo+uop
,相当于uop
。我会看看能否在我的答案中更好地解释这一点。@FatihAkici:我已经更新了答案,希望能更清楚。如果您认为它还需要更多的工作,请告诉我。哦,最后一个循环是在orderList上迭代,而不是在orders上。我的错,谢谢你澄清CA+1on@法蒂哈奇:没问题。我第一次读到这个问题时也感到困惑——我觉得“这根本不是在做同样的事情!”