我正在尝试计算列表中值的平方和。以下是三个均计算所需值的变体。我想知道哪个是最有效的。我希望第三个装箱效率更高,因为自动装箱仅执行一次。
// sum of squares
int sum = list.stream().map(x -> x * x).reduce((x, y) -> x + y).get();
System.out.println("sum of squares: " + sum);
sum = list.stream().mapToInt(x -> x * x).sum();
System.out.println("sum of squares: " + sum);
sum = list.stream().mapToInt(x -> x).map(x -> x * x).sum();
System.out.println("sum of squares: " + sum);
如有疑问,请测试!使用jmh,我在100k元素的列表上得到以下结果(以微秒为单位,更好):
Benchmark Mode Samples Score Error Units
c.a.p.SO32462798.for_loop avgt 10 119.110 0.921 us/op
c.a.p.SO32462798.mapToInt avgt 10 129.702 1.040 us/op
c.a.p.SO32462798.mapToInt_map avgt 10 129.753 1.516 us/op
c.a.p.SO32462798.map_reduce avgt 10 1262.802 12.197 us/op
c.a.p.SO32462798.summingInt avgt 10 134.821 1.203 us/op
因此,从快到慢,您已经拥有:
for(int i : list) sum += i*i;
mapToInt(x -> x * x).sum()
和 mapToInt(x -> x).map(x -> x * x).sum()
collect(Collectors.summingInt(x -> x * x))
map(x -> x * x).reduce((x, y) -> x + y).get()
请注意,结果在很大程度上取决于JIT优化。如果映射中的逻辑更加复杂,则某些优化可能不可用(较长的代码=较少的内联),在这种情况下,流版本可能比for循环花费4-5倍的时间-
但是,如果该逻辑占用大量CPU资源,差异将再次减小。对您的实际应用程序进行性能分析将为您提供更多信息。
基准代码供参考:
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
public class SO32462798 {
List<Integer> list;
@Setup public void setup() {
list = new Random().ints(100_000).boxed().collect(toList());
}
@Benchmark public int for_loop() {
int sum = 0;
for (int i : list) sum += i * i;
return sum;
}
@Benchmark public int summingInt() {
return list.stream().collect(Collectors.summingInt(x -> x * x));
}
@Benchmark public int mapToInt() {
return list.stream().mapToInt(x -> x * x).sum();
}
@Benchmark public int mapToInt_map() {
return list.stream().mapToInt(x -> x).map(x -> x * x).sum();
}
@Benchmark public int map_reduce() {
return list.stream().map(x -> x * x).reduce((x, y) -> x + y).get();
}
}
问题内容: 我刚开始,最近经历了一个ODM框架。 在文档上,我找不到为什么需要使用。我可以给出的一个原因是,我们可以从定义应用程序架构。 我正在寻找更多可能的原因,以及吸引我使用的需求。 请列出所有可能的优点和使用理由/需要。 问题答案: 主要优势是相对于纯mongo的抽象。 来自SQL数据库类型的许多开发人员对于使用未定义结构的动态集合感到非常不舒服。因此, 模式 首先可以帮助您。 此外,它实现
问题是下面的代码片段没有删除数据库中的记录。 然而,如果我打电话给session。flush()删除后,它可以完美地工作。请注意,我没有使用任何交易。 在Session类的JavaDoc中,delete方法的描述如下: 从数据存储中删除持久实例。参数可以是与接收会话相关联的实例,也可以是具有与现有持久状态相关联的标识符的瞬态实例。 我在网上看到了很多代码片段,它们表明在delete()之后不需要调
问题内容: 您好,我正在构建Spring-Hibernate应用程序。我真的需要从下面进行配置吗? 我已经在我的root-context.xml中设置了注释驱动 现在是否不应该使用注释@Entity自动hibernate此包中的所有内容并将其转换为table?就目前而言,没有annotatedClasses的他不会从实体创建表 问题答案: 使用 文档,卢克! […] AnnotationSessi
在mclients.get(0).send(msg1)行中,我正在使索引脱离界限异常。mClients是附加到此服务并在绑定过程中存储的客户端数组。 代码与链接远程信使服务示例部分http://developer.android.com/reference/android/app/service.html完全相同,只是我在服务中添加了一个onStartCommand
本文向大家介绍为什么要设计 后缀表达式,有什么好处?相关面试题,主要包含被问及为什么要设计 后缀表达式,有什么好处?时的应答技巧和注意事项,需要的朋友参考一下 考察点:逆波兰表达式 后缀表达式又叫逆波兰表达式,逆波兰记法不需要括号来标识操作符的优先级。
我必须在下面的地图中输入一个整数值。 当我运行上面的代码我得到下面的错误,有人能帮我吗