我有这种方法,生成一些点并添加到新列表中。这样做的缺点是每次都会产生太多的物体。
现在,我想回到点消费者的消费者,比如:
PointConsumer { void apply(int x, int y); }
PointIterator { void apply(PointConsumer pc); }
每当我生成一个点时,我会将一个新的lambda与旧的lambda连接起来:
pointIterator = pc -> { pointIterator.apply(pc); pc.apply(x, y); }
这种方法比前一种方法更慢还是更多内存消费者?如果差异更大或更小,请不要理会。 p>
答案 0 :(得分:5)
这是一个JMH基准,我从你非常普遍的问题中理解为你的想法。我希望它可以帮助您对所提出的效率做出一些结论。
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(Measure.SIZE)
@Warmup(iterations = 5, time = 100, timeUnit=MILLISECONDS)
@Measurement(iterations = 5, time = 200, timeUnit=MILLISECONDS)
@State(Scope.Thread)
@Threads(1)
@Fork(1)
public class Measure
{
public static final int SIZE = 1;
private static final int LIMIT = 50;
interface PointConsumer { void apply(int x, int y); }
interface PointIterator { void apply(PointConsumer pc); }
PointIterator pointIterator;
List<Point> points;
@Setup public void setup() {
pointIterator = pc -> {};
range(0,LIMIT).forEach(x -> range(0,LIMIT).forEach(y -> {
final PointIterator pi = pointIterator;
pointIterator = pc -> { pi.apply(pc); pc.apply(x, y); };
}));
points = range(0,LIMIT).mapToObj(i->i).flatMap(
x -> range(0,LIMIT).mapToObj(y -> new Point(x,y)))
.collect(toList());
}
@Benchmark public int pointIterator() {
final int sum[] = {0};
pointIterator.apply((x,y) -> sum[0] += x + y );
return sum[0];
}
@Benchmark public int list() {
int sum = 0;
for (Point p : points) sum += p.x + p.y;
return sum;
}
}
测量结果:
Benchmark Mode Samples Score Error Units
o.s.Measure.list avgt 5 3,921 ± 0,408 us/op
o.s.Measure.pointIterator avgt 5 17,970 ± 1,740 us/op
我的结论:
ArrayList
方法慢;