为什么java DirectoryStream执行得这么慢?

为什么java DirectoryStream执行得这么慢?,第1张

为什么java DirectoryStream执行得这么慢?

Files.list()是O(N) *** 作,而排序是O(N log N)。排序内部的 *** 作更重要。鉴于比较结果不同,这是最有可能的解释。在C:/ Windows
/ System32下,有许多文件的修改日期相同,这意味着会经常检查文件的大小。

为了表明大部分时间都没有花在FIles.list(dir)Stream中,我优化了比较,因此每个文件获取一次有关文件的数据。

import java.io.File;import java.io.IOException;import java.io.UncheckedIOException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.attribute.FileTime;import java.util.Arrays;import java.util.Comparator;import java.util.List;import java.util.stream.Collectors;import java.util.stream.Stream;public class FileSorter {    // This sorts from old to young and from big to small    Comparator<Path> timeSizeComparator = (Path o1, Path o2) -> {        int sorter = 0;        try { FileTime lm1 = Files.getLastModifiedTime(o1); FileTime lm2 = Files.getLastModifiedTime(o2); if (lm2.compareTo(lm1) == 0) {     Long s1 = Files.size(o1);     Long s2 = Files.size(o2);     sorter = s2.compareTo(s1); } else {     sorter = lm1.compareTo(lm2); }        } catch (IOException ex) { throw new UncheckedIOException(ex);        }        return sorter;    };    public String[] getSortedFileListAsArray(Path dir) throws IOException {        Stream<Path> stream = Files.list(dir);        return stream.sorted(timeSizeComparator).     map(Path::getFileName).map(Path::toString).toArray(String[]::new);    }    public List<String> getSortedFileListAsList(Path dir) throws IOException {        Stream<Path> stream = Files.list(dir);        return stream.sorted(timeSizeComparator).     map(Path::getFileName).map(Path::toString).collect(Collectors.     toList());    }    public String[] sortByDateAndSize(File[] fileList) {        Arrays.sort(fileList, (File o1, File o2) -> { int r = Long.compare(o1.lastModified(), o2.lastModified()); if (r != 0) {     return r; } return Long.compare(o1.length(), o2.length());        });        String[] fileNames = new String[fileList.length];        for (int i = 0; i < fileNames.length; i++) { fileNames[i] = fileList[i].getName();        }        return fileNames;    }    public List<String> getSortedFile(Path dir) throws IOException {        return Files.list(dir).map(PathInfo::new).sorted().map(p -> p.getFileName()).collect(Collectors.toList());    }    static class PathInfo implements Comparable<PathInfo> {        private final String fileName;        private final long modified;        private final long size;        public PathInfo(Path path) { try {     fileName = path.getFileName().toString();     modified = Files.getLastModifiedTime(path).toMillis();     size = Files.size(path); } catch (IOException ex) {     throw new UncheckedIOException(ex); }        }        @Override        public int compareTo(PathInfo o) { int cmp = Long.compare(modified, o.modified); if (cmp == 0)     cmp = Long.compare(size, o.size); return cmp;        }        public String getFileName() { return fileName;        }    }    public static void main(String[] args) throws IOException {        // File (io package)        File f = new File("C:\Windows\system32");        // Path (nio package)        Path dir = Paths.get("C:\Windows\system32");        FileSorter fs = new FileSorter();        long before = System.currentTimeMillis();        String[] names = fs.sortByDateAndSize(f.listFiles());        long after = System.currentTimeMillis();        System.out.println("Run time of Arrays.sort: " + ((after - before)));        long before2 = System.currentTimeMillis();        String[] names2 = fs.getSortedFileListAsArray(dir);        long after2 = System.currentTimeMillis();        System.out.println("Run time of Stream.sorted as Array: " + ((after2 - before2)));        long before3 = System.currentTimeMillis();        List<String> names3 = fs.getSortedFileListAsList(dir);        long after3 = System.currentTimeMillis();        System.out.println("Run time of Stream.sorted as List: " + ((after3 - before3)));        long before4 = System.currentTimeMillis();        List<String> names4 = fs.getSortedFile(dir);        long after4 = System.currentTimeMillis();        System.out.println("Run time of Stream.sorted as List with caching: " + ((after4 - before4)));    }}

这会在我的笔记本电脑上打印。

Run time of Arrays.sort: 1980Run time of Stream.sorted as Array: 1295Run time of Stream.sorted as List: 1228Run time of Stream.sorted as List with caching: 185

如您所见,大约有85%的时间用于重复获取文件的修改日期和大小。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5561335.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存