Threads verbessern die Performance NICHT ?

JavaBeginnerWithNB

Aktives Mitglied
Hallo,

ich habe ein Programm geschrieben, dass alle Dateien im Laufwerk C:\ ausgeben soll.
Dies macht er zwar schon, aber bis alle Pfade ausgegeben sind, dauert es eine Weile. Ich habe Threads benutzt, um die Bearbeitung schneller zu machen. Dies funktioniert leider nicht. Was mache ich hier falsch ? Für einen Hinweis würde ich mich freuen 🙂
Code:
package test2;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Test2 extends Thread {
     
    public Test2(String name) {
        super(name);
    }
   
    @Override
    public void run() {             
        int i = 0;
        File[] l = File.listRoots();                       
        ArrayList<File> files = getPaths(l[0], new ArrayList<>()); 
        if(files == null) return; 
        try { 
            for (File file : files) {
                 System.out.println(++i + " - " + getName() + ":\t" + file.getCanonicalPath()); 
            }
        } catch (IOException e) { 
        } 
    }
   
    public static void main(String[] args) { 
        Test2 t = new Test2("Finder1");       
        Test2 t2 = new Test2("Finder2");       
        Test2 t3 = new Test2("Finder3");       
        Test2 t4 = new Test2("Finder4");   
        Test2 t5 = new Test2("Finder5");       
        Test2 t6 = new Test2("Finder6");       
        Test2 t7 = new Test2("Finder7");       
        Test2 t8 = new Test2("Finder8");
        t.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
        t6.start();
        t7.start();
        t8.start();
    }                             

    private static ArrayList<File> getPaths(File file, ArrayList<File> list) { 
        if (file == null || list == null || !file.isDirectory()) 
            return null; 
        File[] fileArr = file.listFiles();
        if(fileArr != null) {
            for (File f : fileArr) { 
                if (f.isDirectory() && !f.isHidden()) { 
                    getPaths(f, list); 
                } 
                try {
                    if(file.getCanonicalPath().contains(".")) { 
                        list.add(f);
                    }
                } catch (IOException ex) {
                }
            } 
        }
        return list; 
    } 
}
 
Häh? Du machst doch jetzt achtmal dasselbe. Jeder Thread listet doch jetzt die gesamte Verzeichnisstruktur auf, statt, dass es nur ein einzelner Thread macht, oder dass sich Threads die aufzulistenden Ordner aufteilen (Data Parallelism), was wahrscheinlich sowieso nichts bringen würde, weil der Bottleneck hier das Dateisystem ist und es nicht schneller arbeiten würde, wenn es von 8 statt nur einem Thread mit Anfragen befeuert wird.
Also ich würde fast sagen, dass das Ganze jetzt ca. 8-mal so lange dauert.

Mehrere Threads bringen etwas, wenn:
- die Aufgabe sowieso parallelisiert werden kann und auch parallelisiert wird; entweder durch "Data Parallelism" (parallele Threads arbeiten auf unterschiedlichen Teilen der Daten) oder durch "Function/Task Parallelism" (parallele Threads machen tatsächlich etwas anderes/führen andere Befehle aus)
- eine relativ hohe artihmetische Dichte in der Aufgabe steckt (also: das meiste, was zu tun ist, Operationen sind, die nur die Prozessorkerne selbst auslasten und nicht I/O Subsysteme wie z.B. den Speicherbus oder sogar die Festplatte...)
 
weil der Bottleneck hier das Dateisystem ist und es nicht schneller arbeiten würde, wenn es von 8 statt nur einem Thread mit Anfragen befeuert wird.
Sollte das nicht von einigen Faktoren abhängig sein? SSD oder rotating disk, Scheduling-Strategie des Controllers, Fragmentierung des Dateisystems sollten doch eine Rolle spielen.
 
Parallelisierung kann dir etwas bringen, wenn du mit den Dateien mehr machst, als nur den Namen auszugeben.
Wenn eine Auswertung stattfinden soll, kannst du beispielsweise einen Ringpuffer verwenden, ein Thread ist dafür zuständig, die Dateien auszulesen und diesen Puffer zu befüllen, ein oder mehrere Threads kümmern sich um die Auswertung der einzelnen Dateien.
 

Neue Themen


Zurück
Oben