描述
此程序的目标是从用户填充orderList 订单和productList foreach那些订单。 (请忽略此伪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);
}
}
我的想法
因此第二个程序更快,更正确吗?
答案 0 :(得分:7)
<强>概述强>
您对第二种情况的分析是错误的。由于第一个循环的每个内部事物的orderlist中都有一个条目,foreach(Order o in orderList)
循环遍历n ^ 2个项目。虽然说有一个免责声明,因为它代表了很多东西,所以n在这里没有多大意义。
最好是使用u,o和p来查看它。
案例1
第一个显然是O(uop)
。
案例2
这种情况有两组循环。第一对循环是O(uo)
,正如您所期望的那样..
然后第二对循环以uo
项的循环开始,然后是O(p)的内循环,因此第二对是O(uop)
。总的来说,它使O(uo)+O(uop)
等同于O(uop)
,与案例1相同。
基本上第二种情况只是稍微移动一下,实际上根本没有改变基本算法。
真实世界
与往常一样,如果您实际关注的是真实世界的性能,而不仅仅是理论上的算法复杂性(在查看特定情况时并不总是有用),那么请对两种技术的性能进行基准测试。