相关疑难解决方法(0)

Arrays.stream().map().sum()的不稳定性能

我偶然发现了一个非常不稳定的性能曲线实例,它对原始数组进行了非常简单的map/reduce操作.这是我的jmh基准代码:

@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(Measure.ARRAY_SIZE)
@Warmup(iterations = 300, time = 200, timeUnit=MILLISECONDS)
@Measurement(iterations = 1, time = 1000, timeUnit=MILLISECONDS)
@State(Scope.Thread)
@Threads(1)
@Fork(1)
public class Measure
{
  static final int ARRAY_SIZE = 1<<20;
  final int[] ds = new int[ARRAY_SIZE];

  private IntUnaryOperator mapper;

  @Setup public void setup() {
    setAll(ds, i->(int)(Math.random()*(1<<7)));
    final int multiplier = (int)(Math.random()*10);
    mapper = d -> multiplier*d;
  }

  @Benchmark public double multiply() {
    return Arrays.stream(ds).map(mapper).sum();
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是典型输出的片段:

# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/bin/java
# VM options: <none>
# Warmup: 300 iterations, …
Run Code Online (Sandbox Code Playgroud)

java java-8 jmh

42
推荐指数
1
解决办法
1859
查看次数

Java方法调用性能

我有这段代码做范围最小查询.当t = 100000时,i和j总是在每个输入行中改变,它在Java 8u60中的执行时间约为12秒.

for (int a0 = 0; a0 < t; a0++) {
    String line = reader.readLine();
    String[] ls = line.split(" ");
    int i = Integer.parseInt(ls[0]);
    int j = Integer.parseInt(ls[1]);
    int min = width[i];
    for (int k = i + 1; k <= j; k++) {
        if (min > width[k]) {
            min = width[k];
        }
    }
    writer.write(min + "");
    writer.newLine();
}
Run Code Online (Sandbox Code Playgroud)

当我提取新方法以找到最小值时,执行时间快4倍(约2.5秒).

    for (int a0 = 0; a0 < t; a0++) {
        String line = reader.readLine();
        String[] …
Run Code Online (Sandbox Code Playgroud)

java performance

11
推荐指数
1
解决办法
1291
查看次数

Lambda性能改进,Java 8 vs 11

我在lambda vs方法参考上运行了一些JMH测试,看起来类似于:

IntStream......reduce(Integer::max)
vs.
IntSream.......reduce((i1, i2) -> Integer.max(i1, i2))
Run Code Online (Sandbox Code Playgroud)

我注意到的是,与Java中的lambda相比,方法引用的执行速度大约是lambda的5倍。当我在Java 11中运行测试时,两种方法的执行时间都与Java中方法引用的执行速度差不多。 8.因此,Java 11中的lambda和方法引用之间在性能上没有重大区别。

我的问题是:从Java 8到11进行了哪些改进以提高性能?我正在使用OpenJDK。

编辑我的基准:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 1, jvmArgs = {"-XX:CompileThreshold=5000"})
@Warmup(iterations = 2)
public class FindMaxInt {

@Param({"10000", "1000000", "10000000"})
private int n;

private List<Integer> data;

@Setup
public void setup(){
    data = createData();
}

@Benchmark
public void streamWithMethodReference(final Blackhole blackhole){
    int max = data.stream().mapToInt(Integer::intValue).reduce(Integer.MIN_VALUE, Integer::max);
    blackhole.consume(max);
}

@Benchmark
public void streamWithLambda(final Blackhole blackhole){
    int max = data.stream().mapToInt(Integer::intValue).reduce(Integer.MIN_VALUE, (i1, i2) -> Integer.max(i1, i2));
    blackhole.consume(max);
}
Run Code Online (Sandbox Code Playgroud)

java performance lambda jvm java-stream

9
推荐指数
1
解决办法
1120
查看次数

现代Java编译器/ JVM内联函数/方法是否完全从一个地方调用?

我发现C++编译器这样做但我想知道Java编译器是否也这样做,因为在那个答案中他们说添加静态会这样做但是静态在java和C++中是不同的.在我的情况下表现会重要,因为我使用被称为每帧只有一次在一场比赛中循环,并呼吁无处功能,使其更易于阅读
在我的代码我有它设置了与此类似,只是多了很多电话

while(running)
{
    update();
    sync();
}
Run Code Online (Sandbox Code Playgroud)

然后update(),render()会调用更多调用其他方法的方法

private final void update()
{
    switch(gameState)
    {
        case 0:
            updateMainMenu();
            renderMainMenu();
            break;
        case 1:
            updateInGame();
            renderInGame();
            break;
         //and so on
    }
}

private final void updateInGame()
{
    updatePlayerData();
    updateDayCycle();
    //and so on
}

private final void updatePlayerData()
{
    updateLocation();
    updateHealth();
    //and so on
}
Run Code Online (Sandbox Code Playgroud)

那么编译器是否会内联这些函数,因为它们只在同一位置每帧使用一次?

如果这是一个不好的问题,请告诉我,我将删除它.

java performance code-organization

5
推荐指数
1
解决办法
4196
查看次数

为什么使用流的代码在Java 9中的运行速度比Java 8快得多?

我在解决Euler项目的问题205时发现了这一点.问题如下:

彼得有九个四面(金字塔)骰子,每个骰子都有编号为1,2,3,4的面孔.科林有六个六面(立方体)骰子,每个骰子都有编号为1,2,3,4,5,6的面孔.

彼得和科林掷骰子并比较总数:总得分最高.如果总数相等,结果是平局.

金字塔皮特击败立方科林的可能性是多少?将您的答案四舍五入到0.abcdefg形式的七位小数

我用Guava写了一个天真的解决方案:

import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSet;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

public class Problem205 {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        List<Integer> peter = Sets.cartesianProduct(Collections.nCopies(9, ImmutableSet.of(1, 2, 3, 4)))
                .stream()
                .map(l -> l
                        .stream()
                        .mapToInt(Integer::intValue)
                        .sum())
                .collect(Collectors.toList());
        List<Integer> colin = Sets.cartesianProduct(Collections.nCopies(6, ImmutableSet.of(1, 2, 3, 4, 5, 6)))
                .stream()
                .map(l -> l
                        .stream()
                        .mapToInt(Integer::intValue)
                        .sum())
                .collect(Collectors.toList());

        long startTime2 = System.currentTimeMillis();
        // IMPORTANT BIT HERE! v
        long solutions = …
Run Code Online (Sandbox Code Playgroud)

java performance java-8 java-stream java-9

3
推荐指数
1
解决办法
1145
查看次数

标签 统计

java ×5

performance ×4

java-8 ×2

java-stream ×2

code-organization ×1

java-9 ×1

jmh ×1

jvm ×1

lambda ×1