Может ли кто-нибудь сказать мне, почему использование java 8 stream/lambda намного медленнее, чем для каждого цикла в коде ниже?java 8 уникальный набор ключей из множества карт медленный, используя lambda
Set<Map<Path, String>> set = new HashSet<>();
Map<Path, String> map1 = new HashMap<>();
map1.put(Paths.get("foo"), "bar");
set.add(map1);
Map<Path, String> map2 = new HashMap<>();
map2.put(Paths.get("foo"), "ham");
set.add(map2);
long start = System.currentTimeMillis();
Set<Path> uniqueFromStream = set.stream().flatMap(m -> m.keySet().stream()).collect(Collectors.toSet());
System.err.println("miliseconds for streams: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
Set<Path> uniqueFromLoop = new HashSet<>();
for(final Map<Path,String> map : set){
uniqueFromLoop.addAll(map.keySet());
}
System.err.println("miliseconds for loops: " + (System.currentTimeMillis() - start));
, когда я запускаю его, в среднем потоки/лямбда 63 милисекунд, но для каждого цикла составляет 0 миллисекунды!
лямбды и 'Stream's были добавлен для поддержки распараллеливания на больших наборах объектов. Тем не менее, он очень неэффективен для последовательного доступа и изменения небольших наборов данных. Если вы хотите попробовать с параллельной поддержкой, замените '.stream()' на '.parallelStream()' – CraigR8806
. Также существует проблема с загрузкой классов, что этот пример не учитывает. Для потоков нужно загружать намного больше. –
Вы проверяете каждый метод только один раз, что на самом деле не является хорошим эталоном. По крайней мере, вы должны попытаться измерить это в цикле (то есть 1000 раз), чтобы уменьшить влияние JIT, класс-нагрузки и других подобных вещей. Или (лучше), используйте специализированную инфраструктуру микро-бенчмаркинга, такую как [JMH] (http://openjdk.java.net/projects/code-tools/jmh/). В противном случае нельзя доверять тому, что вы наблюдаете на одном тестовом прогоне. – zeppelin