- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 Stream
并行处理一组未知数量的异构远程存储 JSON 文件(文件数量预先未知)。这些文件的大小差异很大,从每个文件 1 个 JSON 记录到某些其他文件中的 100,000 条记录。在这种情况下,JSON 记录表示一个独立的 JSON 对象,表示为文件中的一行。
我真的很想为此使用 Streams,因此我实现了这个 Spliterator
:
public abstract class JsonStreamSpliterator<METADATA, RECORD> extends AbstractSpliterator<RECORD> {
abstract protected JsonStreamSupport<METADATA> openInputStream(String path);
abstract protected RECORD parse(METADATA metadata, Map<String, Object> json);
private static final int ADDITIONAL_CHARACTERISTICS = Spliterator.IMMUTABLE | Spliterator.DISTINCT | Spliterator.NONNULL;
private static final int MAX_BUFFER = 100;
private final Iterator<String> paths;
private JsonStreamSupport<METADATA> reader = null;
public JsonStreamSpliterator(Iterator<String> paths) {
this(Long.MAX_VALUE, ADDITIONAL_CHARACTERISTICS, paths);
}
private JsonStreamSpliterator(long est, int additionalCharacteristics, Iterator<String> paths) {
super(est, additionalCharacteristics);
this.paths = paths;
}
private JsonStreamSpliterator(long est, int additionalCharacteristics, Iterator<String> paths, String nextPath) {
this(est, additionalCharacteristics, paths);
open(nextPath);
}
@Override
public boolean tryAdvance(Consumer<? super RECORD> action) {
if(reader == null) {
String path = takeNextPath();
if(path != null) {
open(path);
}
else {
return false;
}
}
Map<String, Object> json = reader.readJsonLine();
if(json != null) {
RECORD item = parse(reader.getMetadata(), json);
action.accept(item);
return true;
}
else {
reader.close();
reader = null;
return tryAdvance(action);
}
}
private void open(String path) {
reader = openInputStream(path);
}
private String takeNextPath() {
synchronized(paths) {
if(paths.hasNext()) {
return paths.next();
}
}
return null;
}
@Override
public Spliterator<RECORD> trySplit() {
String nextPath = takeNextPath();
if(nextPath != null) {
return new JsonStreamSpliterator<METADATA,RECORD>(Long.MAX_VALUE, ADDITIONAL_CHARACTERISTICS, paths, nextPath) {
@Override
protected JsonStreamSupport<METADATA> openInputStream(String path) {
return JsonStreamSpliterator.this.openInputStream(path);
}
@Override
protected RECORD parse(METADATA metaData, Map<String,Object> json) {
return JsonStreamSpliterator.this.parse(metaData, json);
}
};
}
else {
List<RECORD> records = new ArrayList<RECORD>();
while(tryAdvance(records::add) && records.size() < MAX_BUFFER) {
// loop
}
if(records.size() != 0) {
return records.spliterator();
}
else {
return null;
}
}
}
}
我遇到的问题是,虽然 Stream 一开始并行得很好,但最终最大的文件还是在单个线程中处理。我相信最直接的原因是有据可查的: split 器“不平衡”。
更具体地说,在 Stream.forEach
生命周期的某个点之后,似乎不会调用 trySplit
方法,因此在trySplit
的末尾很少被执行。
请注意从 trySplit 返回的所有 spliterator 如何共享相同的 paths
迭代器。我认为这是平衡所有 spliterator 之间工作的一种非常聪明的方法,但它还不足以实现完全并行性。
我希望首先跨文件进行并行处理,然后当少数大文件仍然处于 split 状态时,我想跨剩余文件的 block 进行并行处理。这就是 trySplit
末尾的 else
block 的意图。
有没有一种简单/简单/规范的方法可以解决这个问题?
最佳答案
您的 trySplit
应该输出相同大小的分割,无论底层文件的大小如何。您应该将所有文件视为一个单元,并每次使用相同数量的 JSON 对象填充 ArrayList 支持的分割器。对象的数量应确保处理一个拆分需要 1 到 10 毫秒:低于 1 毫秒,您开始接近将批处理移交给工作线程的成本,高于此值,您开始面临 CPU 负载不均匀的风险,因为任务粒度太粗。
分割器没有义务报告大小估计,并且您已经正确执行了此操作:您的估计是Long.MAX_VALUE
,这是一个特殊值,表示“无界”。但是,如果您有许多包含单个 JSON 对象的文件,导致批量大小为 1,这将以两种方式损害您的性能:打开-读取-关闭文件的开销可能会成为瓶颈,并且如果您设法逃脱也就是说,与处理一项的成本相比,线程切换的成本可能会很大,从而再次导致瓶颈。
五年前我正在解决类似的问题,你可以看看my solution .
关于java - 你能重新平衡一个未知大小的不平衡 Spliterator 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58601518/
我正在尝试使用谷歌浏览器的 Trace Event Profiling Tool分析我正在运行的 Node.js 应用程序。选择点样本后,我可以在三种 View 之间进行选择: 自上而下(树) 自上而
对于一个可能是菜鸟的问题,我们深表歉意,但尽管在 SO 上研究了大量教程和其他问题,但仍找不到答案。 我想做的很简单:显示一个包含大量数据库存储字符串的 Android ListView。我所说的“很
我已经开始了一个新元素的工作,并决定给 Foundation 5 一个 bash,看看它是什么样的。在创建带有水平字段的表单时,我在文档中注意到的第一件事是它们使用大量 div 来设置样式。所以我在下
我有一个 Windows 窗体用户控件,其中包含一个使用 BeginInvoke 委托(delegate)调用从单独线程更新的第 3 方图像显示控件。 在繁重的 CPU 负载下,UI 会锁定。当我附加
我有一堆严重依赖dom元素的JS代码。我目前使用的测试解决方案依赖于 Selenium ,但 AFAIK 无法正确评估 js 错误(addScript 错误不会导致您的测试失败,而 getEval 会
我正在制作一款基于滚动 2D map /图 block 的游戏。每个图 block (存储为图 block [21][11] - 每个 map 总共 231 个图 block )最多可以包含 21 个
考虑到以下情况,我是前端初学者: 某个 HTML 页面应该包含一个沉重的图像(例如 - 动画 gif),但我不想强制客户缓慢地等待它完全下载才能享受一个漂亮的页面,而是我更愿意给他看一个轻量级图像(例
我正在设计一个小软件,其中包括: 在互联网上获取资源, 一些用户交互(资源的快速编辑), 一些处理。 我想使用许多资源(它们都列在列表中)来这样做。每个都独立于其他。由于编辑部分很累,我想让用户(可能
我想比较两个理论场景。为了问题的目的,我简化了案例。但基本上它是您典型的生产者消费者场景。 (我关注的是消费者)。 我有一个很大的Queue dataQueue我必须将其传输给多个客户端。 那么让我们
我有一个二元分类问题,标签 0 和 1(少数)存在巨大不平衡。由于测试集带有标签 1 的行太少,因此我将训练测试设置为至少 70-30 或 60-40,因此仍然有重要的观察结果。由于我没有过多地衡量准
我是一名优秀的程序员,十分优秀!