-1

I wrote three methods to get a list of files/folders in a directory using for loops, Streams (Java 8) and parallel Streams (Java 8). I see that a for loop is much faster than a Java 8 Stream. I was under the impression that Java 8's Streams are an improvement?

See my methods below:

private static List<String> getListOfFiles() throws Exception {
    long startTime = System.nanoTime();
    List<String> xmlFileList = new ArrayList<String>();
    File[] workspaceFiles = new File(USER_FOLDER).listFiles();
    try {
        for (File file : workspaceFiles) {
            if (!file.toString().contains(FOLDER)) {
                xmlFileList.add(file.getAbsolutePath());
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    long endTime = System.nanoTime();
    long duration = (endTime - startTime);
    System.out.println("Regular For Loop : " + duration);
    return xmlFileList;
}

private static List<String> getListOfFilesStream() throws IOException {
    long startTime = System.nanoTime();

    List<String> listOfFiles = new ArrayList<String>();
    try (Stream<Path> stream = Files.list(Paths.get(USER_FOLDER))) {
        listOfFiles = stream.filter(file -> !file.getFileName().toString().contains(FOLDER))
                .map(filePath -> filePath.toString()).collect(Collectors.toList());
    }
    long endTime = System.nanoTime();
    long duration = (endTime - startTime);
    System.out.println("Stream : " + duration);
    return listOfFiles;
}

private static List<String> getListOfFilesParallel() throws IOException {
    long startTime = System.nanoTime();

    List<String> listOfFiles = new ArrayList<String>();
    try (Stream<Path> stream = Files.list(Paths.get(USER_FOLDER))) {
        listOfFiles = stream.parallel()
                .filter(file -> !file.getFileName().toString().contains(FOLDER))
                .map(filePath -> filePath.toString()).collect(Collectors.toList());
    }
    long endTime = System.nanoTime();
    long duration = (endTime - startTime);
    System.out.println("Parallel Stream : " + duration);
    return listOfFiles;
}

The output is:

Regular For Loop : 406743
Stream : 54629961
Parallel Stream : 3791280

With -XX:+PrintCompilation, -verbose:gc

for loop result :

     50    1       3       java.lang.String::hashCode (55 bytes)
 51    2       3       java.lang.String::charAt (29 bytes)
 51    4     n 0       java.lang.System::arraycopy (native)   (static)
 51    3       3       java.lang.Object::<init> (1 bytes)
 51    5       3       java.lang.String::<init> (82 bytes)
 52    7       3       java.lang.String::equals (81 bytes)
 52    6       3       java.util.Arrays::copyOfRange (63 bytes)
 52    8       3       java.lang.Math::min (11 bytes)
 53    9       3       java.lang.AbstractStringBuilder::ensureCapacityInternal (16 bytes)
 53   10       3       java.lang.String::indexOf (70 bytes)
 54   11       3       java.lang.String::length (6 bytes)
 54   12       1       java.lang.ref.Reference::get (5 bytes)
 54   13       3       java.lang.String::getChars (62 bytes)
 55   14       3       java.lang.String::indexOf (7 bytes)
 55   15       1       java.lang.ThreadLocal::access$400 (5 bytes)
 60   16       3       java.lang.AbstractStringBuilder::append (50 bytes)
 62   17       3       java.lang.System::getSecurityManager (4 bytes)
 62   18       3       java.lang.StringBuilder::append (8 bytes)
 62   20       3       java.lang.AbstractStringBuilder::expandCapacity (50 bytes)
 63   19       3       java.util.Arrays::copyOf (19 bytes)
Regular For Loop : 418313
 63   21       1       java.io.File::getPath (5 bytes)

Stream result :

     49    1       3       java.lang.String::hashCode (55 bytes)
 50    2       3       java.lang.String::charAt (29 bytes)
 50    4     n 0       java.lang.System::arraycopy (native)   (static)
 50    3       3       java.lang.Object::<init> (1 bytes)
 50    5       3       java.lang.String::<init> (82 bytes)
 51    7       3       java.lang.String::equals (81 bytes)
 51    6       3       java.util.Arrays::copyOfRange (63 bytes)
 52    8       3       java.lang.Math::min (11 bytes)
 53   10       3       java.lang.String::indexOf (70 bytes)
 53   11       3       java.lang.String::length (6 bytes)
 53    9       3       java.lang.AbstractStringBuilder::ensureCapacityInternal (16 bytes)
 53   12       1       java.lang.ref.Reference::get (5 bytes)
 53   13       3       java.lang.String::getChars (62 bytes)
 55   14       3       java.lang.String::indexOf (7 bytes)
 55   15       1       java.lang.ThreadLocal::access$400 (5 bytes)
 59   16       3       java.lang.AbstractStringBuilder::append (50 bytes)
 62   17       3       java.lang.System::getSecurityManager (4 bytes)
 70   18       3       java.lang.Number::<init> (5 bytes)
 70   19       3       java.lang.Byte::<init> (10 bytes)
 71   20       3       java.lang.Short::<init> (10 bytes)
 71   21       3       java.lang.Long::<init> (10 bytes)
 72   22     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLL)L (native)   (static)
 73   23       3       java.lang.StringBuilder::append (8 bytes)
 74   25     n 0       sun.misc.Unsafe::getObjectVolatile (native)   
 74   24       3       java.util.concurrent.ConcurrentHashMap::tabAt (21 bytes)
 74   26     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLL)L (native)   (static)
 75   27       1       java.lang.reflect.Method::getName (5 bytes)
 75   28     n 0       java.lang.invoke.MethodHandle::linkToStatic(LL)L (native)   (static)
 75   29       1       java.lang.Class::getClassLoader0 (5 bytes)
 75   30     n 0       java.lang.Object::hashCode (native)   
 75   31       1       java.lang.Enum::ordinal (5 bytes)
 76   32       4       java.lang.String::charAt (29 bytes)
 77    2       3       java.lang.String::charAt (29 bytes)   made not entrant
 78   33     n 0       java.lang.invoke.MethodHandle::linkToStatic(LL)V (native)   (static)
 78   34       1       java.lang.Object::<init> (1 bytes)
 78    3       3       java.lang.Object::<init> (1 bytes)   made not entrant
 78   35       3       java.lang.String::lastIndexOf (52 bytes)
 78   36     n 0       java.lang.invoke.MethodHandle::linkToStatic(LL)J (native)   (static)
 79   38     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLL)L (native)   (static)
 79   37       3       java.lang.ref.Reference::<init> (25 bytes)
 79   39       3       java.util.Arrays::copyOf (19 bytes)
 79   40       3       java.lang.invoke.MemberName::testFlags (16 bytes)
 79   41       3       java.lang.AbstractStringBuilder::append (29 bytes)
 80   42       3       java.lang.Class::getName (21 bytes)
 80   43     n 0       java.lang.Class::isPrimitive (native)   
 80   44       1       java.lang.invoke.MethodType::returnType (5 bytes)
 80   45       3       java.lang.Class::getClassLoader (28 bytes)
 80   46       1       java.lang.invoke.MemberName::getDeclaringClass (5 bytes)
 81   47       3       java.lang.StringBuilder::append (8 bytes)
 81   48       3       jdk.internal.org.objectweb.asm.ByteVector::putUTF8 (142 bytes)
 81   49       3       jdk.internal.org.objectweb.asm.Item::set (143 bytes)
 82   50       3       jdk.internal.org.objectweb.asm.ByteVector::putShort (52 bytes)
 82   51       3       jdk.internal.org.objectweb.asm.ClassWriter::get (49 bytes)
 82   53       3       java.lang.AbstractStringBuilder::expandCapacity (50 bytes)
 83   52       3       jdk.internal.org.objectweb.asm.ByteVector::putByte (39 bytes)
 83   54       1       java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry::hashCode (5 bytes)
 83   55       1       java.util.SubList::access$000 (5 bytes)
 83   56       1       java.util.AbstractList$ListItr::nextIndex (5 bytes)
 84   57       1       java.util.SubList::access$200 (5 bytes)
 84   58       3       java.util.concurrent.ConcurrentHashMap::spread (10 bytes)
 84   59       1       java.lang.String::length (6 bytes)
 84   11       3       java.lang.String::length (6 bytes)   made not entrant
 84   60       3       java.util.Objects::requireNonNull (14 bytes)
 84   61       3       java.lang.invoke.MemberName::isInvocable (7 bytes)
 84   62     n 0       java.lang.Object::getClass (native)   
 85   64       3       java.lang.String::replace (127 bytes)
 85   63       1       java.util.ArrayList::access$100 (5 bytes)
 85   65       3       java.lang.String::lastIndexOf (13 bytes)
 85   66       1       java.util.ArrayList::size (5 bytes)
 85   67   !   3       java.util.concurrent.ConcurrentHashMap::putVal (362 bytes)
 86   71     n 0       java.lang.invoke.MethodHandle::linkToVirtual(LL)L (native)   (static)
 87   69       3       jdk.internal.org.objectweb.asm.Item::<init> (66 bytes)
 87   72     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLL)V (native)   (static)
 87   70       3       jdk.internal.org.objectweb.asm.ClassWriter::put (152 bytes)
 87   73     n 0       java.lang.Class::isArray (native)   
 87   75     n 0       java.lang.invoke.MethodHandle::invokeBasic(L)L (native)   
 87   68   !   3       java.lang.ref.ReferenceQueue::poll (28 bytes)
 87   76     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLL)L (native)   (static)
 87   74       3       java.lang.reflect.Modifier::isStatic (13 bytes)
 87   77       3       jdk.internal.org.objectweb.asm.ClassWriter::newUTF8 (70 bytes)
 88   78       3       java.lang.invoke.MethodType::checkSlotCount (33 bytes)
 88   80     n 0       java.lang.Object::clone (native)   
 88   79       3       java.lang.invoke.MemberName::testAllFlags (7 bytes)
 88   81     n 0       java.lang.invoke.MethodHandle::linkToStatic(L)L (native)   (static)
 88   82       3       java.lang.String::indexOf (166 bytes)
 88   84     n 0       java.lang.invoke.MethodHandle::invokeBasic()L (native)   
 89   86     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LL)L (native)   (static)
 89   83       3       java.lang.AbstractStringBuilder::<init> (12 bytes)
 89   85   !   3       java.lang.invoke.MemberName::getMethodType (208 bytes)
 89   88     n 0       java.lang.invoke.MethodHandle::invokeBasic(LL)L (native)   
 89   89     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLL)L (native)   (static)
 90   87       1       java.lang.invoke.MethodType::form (5 bytes)
 90   90       3       jdk.internal.org.objectweb.asm.ByteVector::put12 (64 bytes)
 90   93     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLL)L (native)   
 90   94     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLL)L (native)   (static)
 90   95       3       java.lang.ref.Reference::<init> (7 bytes)
 90   92       3       java.util.concurrent.ConcurrentHashMap::putIfAbsent (8 bytes)
 90   91       1       java.lang.invoke.MethodType::ptypes (5 bytes)
 90   96       1       java.lang.invoke.LambdaForm$Name::index (5 bytes)
 90   97       1       sun.invoke.util.Wrapper::basicTypeChar (5 bytes)
 90   98     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLL)L (native)   (static)
 91   99       3       java.lang.invoke.MemberName::isConstructor (7 bytes)
 91  100     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLL)L (native)   
 91  101       3       java.lang.invoke.MemberName::getMethodOrFieldType (72 bytes)
 91  103     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLL)L (native)   (static)
 91  106       4       java.lang.String::hashCode (55 bytes)
 91  107     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLL)L (native)   (static)
 92  102       3       java.lang.ref.WeakReference::<init> (6 bytes)
 92  104       3       java.lang.invoke.LambdaForm$BasicType::basicType (19 bytes)
 92  112     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLLL)L (native)   
 92  105       1       java.lang.invoke.LambdaForm$Name::type (5 bytes)
 92  114     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLL)L (native)   (static)
 92  113       3       java.lang.Object::equals (11 bytes)
 92  109       1       java.lang.invoke.LambdaForm$BasicType::basicTypeChar (5 bytes)
 92  108       1       java.lang.invoke.LambdaForm$Name::access$000 (5 bytes)
 92  110       1       java.lang.invoke.LambdaForm$BasicType::access$100 (5 bytes)
 92  111       1       java.lang.invoke.LambdaForm$BasicType::basicTypeClass (5 bytes)
 93  115       3       java.lang.invoke.MemberName::isStatic (8 bytes)
 93  116     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLLLL)L (native)   
 93  117       3       java.lang.invoke.MethodType::hashCode (53 bytes)
 93  119     n 0       sun.misc.Unsafe::putObjectVolatile (native)   
 93  120     n 0       sun.misc.Unsafe::compareAndSwapObject (native)   
 93  121     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLLL)L (native)   (static)
 93  118       3       java.util.concurrent.ConcurrentHashMap::setTabAt (19 bytes)
 93    1       3       java.lang.String::hashCode (55 bytes)   made not entrant
 93  122       3       java.lang.invoke.MethodType$ConcurrentWeakInternSet::expungeStaleElements (27 bytes)
 93  123   !   3       java.util.AbstractList$Itr::next (45 bytes)
 93  125     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLLL)L (native)   (static)
 93  126       3       java.lang.invoke.MethodType::parameterType (7 bytes)
 94  127       3       java.lang.StringBuilder::toString (17 bytes)
 94  124       3       java.util.AbstractList$Itr::checkForComodification (23 bytes)
 94  129     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLLLLL)L (native)   
 94  128       3       java.lang.invoke.LambdaForm::argument (27 bytes)
 94  130     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLLLL)L (native)   (static)
 94  131       3       java.lang.invoke.MethodType::checkPtype (19 bytes)
 94  132     n 0       java.lang.Class::isInterface (native)   
 94  133       3       java.util.Arrays$ArrayList::size (6 bytes)
 94  134       3       java.util.Collections$UnmodifiableCollection$1::hasNext (10 bytes)
 94  135       1       java.lang.invoke.MethodHandle::type (5 bytes)
 94  136       3       java.lang.invoke.MethodTypeForm::canonicalize (233 bytes)
 95  137     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLLLL)L (native)   (static)
 95  140     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLLLLLL)L (native)   
 95  141     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLLLLL)L (native)   (static)
 95  138       3       jdk.internal.org.objectweb.asm.Type::getArgumentsAndReturnSizes (151 bytes)
 95  145     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLLLLL)L (native)   (static)
 96  139       3       java.lang.invoke.InvokerBytecodeGenerator::isStaticallyNameable (116 bytes)
 96  146     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLLLLLLL)L (native)   
 96  147     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLLLLLL)L (native)   (static)
 96  150     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLLLLLL)L (native)   (static)
 97  143       3       jdk.internal.org.objectweb.asm.Frame::execute (2252 bytes)
 97  151     n 0       java.lang.invoke.MethodHandle::invokeBasic(LLLLLLLLLL)L (native)   
 97  153     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LLLLLLLLLLLL)L (native)   (static)
 98  154     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLLLLLLL)L (native)   (static)
 99  156     n 0       java.lang.invoke.MethodHandle::linkToStatic(LLLLLLLLLLLLL)L (native)   (static)
 99  157       4       jdk.internal.org.objectweb.asm.ByteVector::putUTF8 (142 bytes)
100  158     n 0       java.lang.invoke.MethodHandle::linkToStatic(LIL)V (native)   (static)
100  159     n 0       java.lang.invoke.MethodHandle::linkToStatic(ILL)I (native)   (static)
101  152       3       java.util.concurrent.ConcurrentHashMap::get (162 bytes)
102  149  s    3       java.lang.StringBuffer::append (13 bytes)
102  144       3       jdk.internal.org.objectweb.asm.Item::isEqualTo (354 bytes)
103  148       3       java.lang.invoke.MethodType::makeImpl (66 bytes)
103  160     n 0       java.lang.invoke.MethodHandle::linkToStatic(ILLL)L (native)   (static)
103  164     n 0       java.lang.invoke.MethodHandle::invokeBasic(ILL)L (native)   
103  142       3       java.lang.String::substring (79 bytes)
103  165     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LILLL)L (native)   (static)
103  161       3       java.lang.invoke.LambdaForm$Name::initIndex (26 bytes)
104  162       3       java.lang.invoke.LambdaForm$BasicType::basicTypeSlots (8 bytes)
104  168       3       java.util.Arrays$ArrayList::get (7 bytes)
104  163       3       sun.invoke.util.Wrapper::stackSlots (9 bytes)
104  166       3       jdk.internal.org.objectweb.asm.MethodWriter::visitVarInsn (292 bytes)
104  169       3       sun.invoke.util.VerifyAccess::isSamePackage (114 bytes)
105   48       3       jdk.internal.org.objectweb.asm.ByteVector::putUTF8 (142 bytes)   made not entrant
105  175       3       jdk.internal.org.objectweb.asm.Type::getType (269 bytes)
106  170       3       jdk.internal.org.objectweb.asm.Frame::push (110 bytes)
106  174       3       java.lang.String::<init> (10 bytes)
106  173       3       jdk.internal.org.objectweb.asm.ClassWriter::addType (39 bytes)
106  176       3       java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry::<init> (14 bytes)
106  172       3       java.lang.invoke.LambdaForm$BasicType::basicType (172 bytes)
107  167       3       java.lang.invoke.InvokerBytecodeGenerator::emitImplicitConversion (159 bytes)
108  180       3       java.lang.invoke.LambdaForm$NamedFunction::methodType (23 bytes)
108  181       3       jdk.internal.org.objectweb.asm.Frame::type (416 bytes)
108  182       4       java.lang.String::indexOf (70 bytes)
108  179       3       java.lang.StringBuilder::<init> (7 bytes)
109  178       3       java.lang.String::indexOf (25 bytes)
109  184       4       java.lang.String::equals (81 bytes)
109  177       3       java.lang.String::indexOf (7 bytes)
109  183       3       jdk.internal.org.objectweb.asm.Frame::get (46 bytes)
109  185       3       java.lang.invoke.InvokerBytecodeGenerator::emitLoadInsn (21 bytes)
109  186       3       java.lang.invoke.InvokerBytecodeGenerator::loadInsnOpcode (86 bytes)
109   10       3       java.lang.String::indexOf (70 bytes)   made not entrant
110  189       3       java.util.AbstractList$Itr::hasNext (20 bytes)
110  187  s    3       java.lang.StringBuffer::append (15 bytes)
110  188       3       java.lang.AbstractStringBuilder::append (40 bytes)
110  171       1       java.lang.invoke.LambdaForm::arity (5 bytes)
110  155       1       java.lang.invoke.MethodTypeForm::erasedType (5 bytes)
111  190       3       java.util.AbstractCollection::<init> (5 bytes)
112    7       3       java.lang.String::equals (81 bytes)   made not entrant
112  191       3       jdk.internal.org.objectweb.asm.ByteVector::<init> (13 bytes)
112  192       3       jdk.internal.org.objectweb.asm.ByteVector::putByteArray (49 bytes)
112  193     n 0       java.lang.invoke.MethodHandle::linkToStatic(LL)I (native)   (static)
112  194       3       java.lang.invoke.MethodType$ConcurrentWeakInternSet::get (54 bytes)
113  195       3       jdk.internal.org.objectweb.asm.ByteVector::putInt (74 bytes)
113  196       3       jdk.internal.org.objectweb.asm.ByteVector::enlarge (51 bytes)
113  197       3       java.lang.invoke.MemberName::getReferenceKind (12 bytes)
113  198       1       java.lang.invoke.MethodTypeForm::basicType (5 bytes)
113  199       3       java.lang.ClassLoader::checkName (43 bytes)
114  200       3       sun.misc.VM::allowArraySyntax (4 bytes)
115  201     n 0       java.lang.Class::getComponentType (native)   
115  202     n 0       java.lang.invoke.MethodHandle::linkToSpecial(LL)V (native)   (static)
115  203       3       sun.reflect.misc.ReflectUtil::isVMAnonymousClass (19 bytes)
115  204       3       java.util.concurrent.ConcurrentHashMap::addCount (292 bytes)
115  205     n 0       java.lang.invoke.MethodHandle::linkToInterface(LLL)I (native)   (static)
116  207       3       java.util.concurrent.ConcurrentHashMap::casTabAt (20 bytes)
116  206       3       sun.invoke.util.Wrapper::forBasicType (16 bytes)
116  209       3       sun.invoke.util.BytecodeDescriptor::unparseSig (75 bytes)
117  210       3       jdk.internal.org.objectweb.asm.ClassWriter::newClass (9 bytes)
117  208       3       jdk.internal.org.objectweb.asm.ClassWriter::put122 (15 bytes)
118  211       3       java.util.ArrayList::ensureCapacityInternal (23 bytes)
118  212       3       java.util.ArrayList::ensureExplicitCapacity (26 bytes)
118  213       3       java.util.ArrayList::add (29 bytes)
118  214       3       sun.nio.cs.UTF_8$Decoder::decode (779 bytes)
119  216     n 0       java.lang.Thread::currentThread (native)   (static)
Stream : 57870863
GhostCat
  • 137,827
  • 25
  • 176
  • 248
Damien-Amen
  • 7,232
  • 12
  • 46
  • 75
  • 7
    [Obligatory link](http://stackoverflow.com/q/504103/3788176). – Andy Turner Jul 05 '16 at 14:54
  • You're comparing a lot more than just for loops vs streams. For example, you're also comparing classic Java IO vs new NIO. But the big difference could be that during the timing of your streams method, the JVM may have decided that it's worth doing a JIT compilation. So use the proper benchmarking tool, JMH. – DodgyCodeException May 08 '19 at 08:47
  • By the way, assigning `new ArrayList()` to `listOfFiles` is pointless as it always gets reassigned to another list inside the try block. – DodgyCodeException May 08 '19 at 08:55

2 Answers2

1

As useful as it is, the whole "streaming" stuff adds abstraction. That rarely comes for free.

To a certain degree, you always bargain "code quality aspects" for performance. Most of time, the performance impacts might be negligible; or as in your case: even with abstraction in place, you can be doing better, because that very abstraction allows you to switch from "single-threaded" to "multi-threaded" that easily.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

As stated in the comment, your benchmark is prone to errors coming from all sorts of sources and the link shows a good tool for benchmarking is JMH. However, to reduce to learning curve just for now, I've modified your code to introduce iterations that show an interesting aspect of how the JVM works.

public class Main {
    private static final String USER_FOLDER = System.getProperty("user.home");
    private static final String FOLDER = Paths.get(USER_FOLDER, "Documents").toString();
    private static final int ITERATIONS = 10000;

    private static List<String> getListOfFiles(boolean shouldPrint) throws Exception {
        long startTime = System.nanoTime();
        List<String> xmlFileList = new ArrayList<String>();
        File[] workspaceFiles = new File(USER_FOLDER).listFiles();
        try {
            for (File file : workspaceFiles) {
                if (!file.toString().contains(FOLDER)) {
                    xmlFileList.add(file.getAbsolutePath());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        if (shouldPrint)
            System.out.println("Regular For Loop : " + duration / 1000);
        return xmlFileList;
    }

    private static List<String> getListOfFilesStream(boolean shouldPrint) throws IOException {
        long startTime = System.nanoTime();

        List<String> listOfFiles;
        try (Stream<Path> stream = Files.list(Paths.get(USER_FOLDER))) {
            listOfFiles = stream.filter(file -> !file.getFileName().toString().contains(FOLDER))
                    .map(Path::toString)
                    .collect(Collectors.toList());
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        if (shouldPrint)
            System.out.println("Stream : " + duration / 1000);
        return listOfFiles;
    }

    private static List<String> getListOfFilesParallel(boolean shouldPrint) throws IOException {
        long startTime = System.nanoTime();

        List<String> listOfFiles;
        try (Stream<Path> stream = Files.list(Paths.get(USER_FOLDER))) {
            listOfFiles = stream.parallel()
                    .filter(file -> !file.getFileName().toString().contains(FOLDER))
                    .map(Path::toString)
                    .collect(Collectors.toList());
        }
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        if (shouldPrint)
            System.out.println("Parallel Stream : " + duration / 1000);
        return listOfFiles;
    }

    public static void main(String[] args) throws Exception {
        for (int i = 1; i <= ITERATIONS; i++)
            getListOfFiles(i <= 3 || i > ITERATIONS - 3);
        for (int i = 1; i <= ITERATIONS; i++)
            getListOfFilesParallel(i <= 3 || i > ITERATIONS - 3);
        for (int i = 1; i <= ITERATIONS; i++)
            getListOfFilesStream(i <= 3 || i > ITERATIONS - 3);
    }
}

I've changed the methods to only print the timings for the first 3 and last 3 iterations. Here are the results:

Regular For Loop : 508
Regular For Loop : 526
Regular For Loop : 351
Regular For Loop : 180
Regular For Loop : 245
Regular For Loop : 201
Parallel Stream : 6190
Parallel Stream : 854
Parallel Stream : 533
Parallel Stream : 132
Parallel Stream : 255
Parallel Stream : 193
Stream : 1270
Stream : 287
Stream : 267
Stream : 130
Stream : 178
Stream : 168

This shows that once the stream code is JIT-compiled, it is faster on average than the for loop code, at least on my particular machine (I've run it several times and each time got similar results to the above).

To get the JVM to compile a method, you need to run it around 10,000 times. This depends on the JVM version. You could try it on your setup and see what happens.

DodgyCodeException
  • 5,963
  • 3
  • 21
  • 42