Какой самый быстрый способ узнать, сколько непустых строк в файле, используя Java? - PullRequest
0 голосов
/ 27 марта 2009

Какой самый быстрый способ узнать, сколько непустых строк в файле, используя Java?

Ответы [ 4 ]

6 голосов
/ 27 марта 2009

Самый простой способ - использовать BufferedReader и проверить, какие строки пусты. Тем не менее, это относительно медленный путь, потому что он должен создавать объект String для каждой строки в файле. Более быстрый способ - прочитать файл в массивы с помощью read (), а затем выполнить итерацию по массивам для подсчета разрывов строк.

Вот код для двух вариантов; второй занял около 50% времени на моей машине.

public static void timeBufferedReader () throws IOException
{
    long bef = System.currentTimeMillis ();

    // The reader buffer size is the same as the array size I use in the other function
    BufferedReader reader = new BufferedReader(new FileReader("test.txt"), 1024 * 10);
    int counter = 0;
    while (reader.ready())
    {
        if (reader.readLine().length() > 0)
            counter++;
    }

    long after = System.currentTimeMillis() - bef;

    System.out.println("Time: " + after + " Result: " + counter);

}

public static void timeFileReader () throws IOException
{
    long bef = System.currentTimeMillis();

    FileReader reader = new FileReader("test.txt");
    char[] buf = new char[1024 * 10];
    boolean emptyLine = true;
    int     counter = 0;
    while (reader.ready())
    {
        int len = reader.read(buf,0,buf.length);
        for (int i = 0; i < len; i++)
        {
            if (buf[i] == '\r' || buf[i] == '\n')
            {
                if (!emptyLine)
                {
                    counter += 1;
                    emptyLine = true;
                }
            }
            else emptyLine = false;
        }
    }

    long after = System.currentTimeMillis() - bef;

    System.out.println("Time: " + after + " Result: " + counter);

}
5 голосов
/ 28 марта 2009

Я с Limbic System по рекомендации NIO. Я добавил метод NIO в тестовый код Дафны и протестировал его для двух методов:

public static void timeNioReader () throws IOException {
    long bef = System.currentTimeMillis();

    File file = new File("/Users/stu/test.txt");
    FileChannel fc = (new FileInputStream(file)).getChannel(); 
    MappedByteBuffer buf = fc.map(MapMode.READ_ONLY, 0, file.length());
    boolean emptyLine = true;
    int     counter = 0;

    while (buf.hasRemaining())
    {
        byte element = buf.get();

        if (element == '\r' || element == '\n') {
            if (!emptyLine) {
                counter += 1;
                emptyLine = true;
            }
        } else 
            emptyLine = false;

    }

    long after = System.currentTimeMillis() - bef;

    System.out.println("timeNioReader      Time: " + after + " Result: " + counter);

}

Вот подогретые результаты для файла 89 МБ:

timeBufferedReader Time: 947 Result: 747656
timeFileReader     Time: 670 Result: 747656
timeNioReader      Time: 251 Result: 747656

NIO в 2,5 раза быстрее, чем FileReader, и в 4 раза быстрее, чем BufferedReader!

С файлом размером 6,4 МБ результаты еще лучше, хотя время прогрева намного больше.

//jvm start, warming up
timeBufferedReader Time: 121 Result: 53404
timeFileReader     Time: 65 Result: 53404
timeNioReader      Time: 40 Result: 53404

//still warming up
timeBufferedReader Time: 107 Result: 53404
timeFileReader     Time: 60 Result: 53404
timeNioReader      Time: 20 Result: 53404

//ripping along
timeBufferedReader Time: 79 Result: 53404
timeFileReader     Time: 56 Result: 53404
timeNioReader      Time: 16 Result: 53404

Делай из этого что хочешь.

2 голосов
/ 27 марта 2009

Если он действительно должен быть максимально быстрым, вам следует заглянуть в NIO . А затем протестируйте ваш код на целевой платформе, чтобы увидеть, действительно ли он лучше и эффективнее с помощью NIO. Мне удалось улучшить на несколько порядков код, с которым я играл для Netflix Prize . Он включал разбор тысяч файлов в более компактный, быстро загружаемый двоичный формат. NIO оказал большую помощь на моем (медленном) ноутбуке для разработки.

2 голосов
/ 27 марта 2009

Самый простой будет со сканером (да, мне нравится подробный код ... вы можете сделать его физически короче). Scanner () также принимает File, Reader и т. Д., Так что вы можете передать все, что у вас есть.

import java.util.Scanner;


public class Main
{
    public static void main(final String[] argv)
    {
        final Scanner scanner;
        final int     lines;

        scanner = new Scanner("Hello\n\n\nEvil\n\nWorld");
        lines   = countLines(scanner);
        System.out.println("lines = "  + lines);
    }

    private static int countLines(final Scanner scanner)
    {
        int lines;

        lines = 0;

        while(scanner.hasNextLine())
        {
            final String line;

            line = scanner.nextLine();

            if(line.length() > 0)
            {
                lines++;
            }
        }

        return lines;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...