sbool parallelMap2_debug; // Note: an executor passed in is not shut down static L parallelMap2(ThreadPoolExecutor executor default null, Collection l, F1 f) { if (l(l) <= 1) ret map(f, l); ret parallelMap2(executor, iterator(l), l(l), f); } static L parallelMap2(ThreadPoolExecutor executor default null, Iterator it, final int count, final F1 f) ctex { if (executor == null && coresToUse_fixed() == 1) ret map(f, iterable(it)); ThreadPoolExecutor e = executor == null ? defaultThreadPoolExecutor() : executor; L> futures = emptyList(count); new Var error; if (parallelMap2_debug) print("parallelMap2: " + count + " elements, " + e.getMaximumPoolSize() + " threads"); long time = sysNow(); try { int i = 0; for (final A o : iterable(it)) { ++i; final int _i = i; futures.add(e.submit(() -> { try { ret callF(f, o); } catch e2 { error.set(e2); null; } })); } /*if (parallelMap2_debug) print("parallelMap2: scheduling done after " + (sysNow()-time));*/ L out = getFutures(futures); if (error.has()) throw rethrow(error!); if (parallelMap2_debug) print("parallelMap2: main done after " + (sysNow()-time)); ret out; } finally { if (executor == null) e.shutdown(); } } static L lambdaMapLike parallelMap2(IF1 f, Cl l) { ret parallelMap2(l, if1ToF1(f)); }