当前位置: 首页 > 工具软件 > StringSpliter > 使用案例 >

java spliter_java – 什么时候Spliter停止分裂?

詹亮
2023-12-01

一般来说,你不知道在尝试Advisor或forEachRemaining的消费者中做了多少工作.流管道和FJP都不知道这一点,因为它取决于用户提供的代码.它可以比分割程序快得多或慢得多.例如,您可能有两个元素的输入,但每个元素的处理需要一个小时,因此拆分此输入是非常合理的.

我通常尽可能多地分割输入.有三个技巧可以用来改善分裂:

>如果难以均匀分割,但您可以跟踪(或至少粗略估计)每个子部分的大小,可以自由分割.流的实现将在更大的部分进一步分裂.不要忘记SIZED和SUBSIZED的特点.

>将分割的重要部分移动到下一个tryAdvance / forEachRemaining调用.例如,假设你有一个已知的排列数,而在trySplit中,你将会跳到其他排列.这样的事情

public class MySpliterator implements Spliterator {

private long position;

private String currentPermutation;

private final long limit;

MySpliterator(long position, long limit, String currentPermutation) {

this.position = position;

this.limit = limit;

this.currentPermutation = currentPermutation;

}

@Override

public Spliterator trySplit() {

if(limit - position <= 1)

return null;

long newPosition = (position+limit)>>>1;

Spliterator prefix =

new MySpliterator(position, newPosition, currentPermutation);

this.position = newPosition;

this.currentPermutation = calculatePermutation(newPosition); // hard part

return prefix;

}

...

}

将硬件部分移动到下一个tryAdvance调用,如下所示:

@Override

public Spliterator trySplit() {

if(limit - position <= 1)

return null;

long newPosition = (position+limit)>>>1;

Spliterator prefix =

new MySpliterator(position, newPosition, currentPermutation);

this.position = newPosition;

this.currentPermutation = null;

return prefix;

}

@Override

public boolean tryAdvance(Consumer super String> action) {

if(currentPermutation == null)

currentPermutation = calculatePermutation(position); // hard part

...

}

这样,硬件部分也将与前缀处理并行执行.>如果您目前没有这么多的元素(例如,不到10个),并且分配被要求,那么提升到一半的元素收集到数组中可能是很好的,然后创建一个基于数组的分割器对于这个前缀(类似于在AbstractSpliterator.trySplit()中完成).在这里,您可以控制所有代码,因此您可以提前测量trySplit的正常速度,而不是tryAdvance,并且在切换到基于阵列的拆分时估计阈值.

 类似资料: