如何提高执行时间的性能?他们有更好的方式读取此文件吗?

时间:2018-09-12 05:23:08

标签: java performance randomaccessfile

我正在尝试使用多个线程拆分文本文件。该文件的大小为1 GB。我正在按字符读取文件。执行时间为24分54秒。他们可以减少执行时间的任何更好的方式,而不是按char读取文件。 我很难找到一种可以减少执行时间的方法。如果还有其他更好的方法来分割带有多个线程的文件,请也建议我。我对Java很陌生。

任何帮助将不胜感激。 :)

declare @tbl table(name varchar(20))

insert into @tbl values ('Abdul$Rahim')

insert into @tbl values('Tariq$Jameel')

select

PARSENAME(replace(name,'$','.'),2) as firstname,
PARSENAME(replace(name,'$','.'),1) as lastname

from @tbl

1 个答案:

答案 0 :(得分:0)

最快的方法是将文件逐段映射到内存中(将一个大文件整体映射可能会导致不希望的副作用)。它将跳过一些相对昂贵的复制操作。操作系统会将文件加载到RAM中,而JRE会将其作为ByteBuffer形式的堆外内存区域视图显示给您的应用程序。通常,您可以压缩性能的最后2倍/ 3倍。

内存映射方式需要大量的帮助程序代码(请参阅底部的片段),这并不总是最佳的战术方式。相反,如果您的输入是基于行的,并且您只需要合理的性能(现在可能没有),那么只需执行以下操作即可:

import java.nio.Files;
import java.nio.Paths;
...
File.lines(Paths.get("/path/to/the/file"), StandardCharsets.ISO_8859_1)
//      .parallel() // parallel processing is still possible
        .forEach(line -> { /* your code goes here */ });

为了对比,通过内存映射使用文件的代码的工作示例如下所示。对于固定大小的记录(当可以精确选择段以匹配记录边界时),可以并行处理后续段。

static ByteBuffer mapFileSegment(FileChannel fileChannel, long fileSize, long regionOffset, long segmentSize) throws IOException {
    long regionSize = min(segmentSize, fileSize - regionOffset);

    // small last region prevention
    final long remainingSize = fileSize - (regionOffset + regionSize);
    if (remainingSize < segmentSize / 2) {
        regionSize += remainingSize;
    }

    return fileChannel.map(FileChannel.MapMode.READ_ONLY, regionOffset, regionSize);
}

...

final ToIntFunction<ByteBuffer> consumer = ...
try (FileChannel fileChannel = FileChannel.open(Paths.get("/path/to/file", StandardOpenOption.READ)) {
    final long fileSize = fileChannel.size();

    long regionOffset = 0;
    while (regionOffset < fileSize) {
        final ByteBuffer regionBuffer = mapFileSegment(fileChannel, fileSize, regionOffset, segmentSize);
        while (regionBuffer.hasRemaining()) {
            final int usedBytes = consumer.applyAsInt(regionBuffer);
            if (usedBytes == 0)
                break;
        }
        regionOffset += regionBuffer.position();
    }
} catch (IOException ex) {
    throw new UncheckedIOException(ex);
}