powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Быстрое чтение и разбор файла
25 сообщений из 158, страница 1 из 7
Быстрое чтение и разбор файла
    #38562779
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Какой самый быстрый способ чтения файла в java ?

Использовал самый простой построчный подход :
Файл вида : строки разделенные \t табом.

name1\tname2\tname3\tname4\tname5
name6\tname7\tname8\tname9\tname10

....
namen\tnamez\tnamex\tnamek\tnamep


( на файле в 1 млн строк ) BufferedReader - тратит 2 секунды (чисто на чтение )
это очень долго.


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 
LinkedList<ArrayList<String>> list = new LinkedList<ArrayList<String>>();
BufferedReader in = new BufferedReader(new InputStreamReader(NewClass.class.getResourceAsStream("in.txt")));
        String str = null;
        ArrayList<String> rlst = null;
        while ((str = in.readLine()) != null) {
            String arr[] = str.split("\t");
            rlst = new ArrayList<String>(Arrays.asList(arr));
            list.addLast(rlst);
        }
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38562782
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй размер буфера побольше указать. Для больших файлов может помочь.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38562794
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

особой разницы нет , если увеличить буфер в 4 раза - работает медленнее в 2 раза ...

нашел только это : самый быстрый способ чтения в java:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
      RandomAccessFile raf = new RandomAccessFile("test.test", "rw");
        raf.writeInt(145);
        raf.writeUTF(" ");
        raf.writeUTF("afdfjhf");
        raf.writeUTF(" ");
        FileChannel fchan = raf.getChannel();
        System.out.println(fchan.size());
        MappedByteBuffer buf = fchan.map(FileChannel.MapMode.READ_WRITE, 0, fchan.size());



но это не для строк.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38562803
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1 особой разницы нет , если увеличить буфер в 4 раза - работает медленнее в 2 раза ...

И это точно никак не связано с readLine? Т.е. мерял исключительно IO?
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38562971
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1
Файлы состоят из байт, а не строк... Это намёк на то, что можно исключить операцию разбора буфера на строки, заполнять ArrayList<String> по мере парсинга данных, по нахождению символов перевода строки "укладывать" ArrayList в связанный список.

тогда избавитесь от накладок по памяти и времени связанных с двойным проходом по буферу. Т.е. всё должно происходить в один проход...
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563060
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
за сколько времени этот же файл копируется в /dev/null?
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563154
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapokза сколько времени этот же файл копируется в /dev/null?Это зависит от того чем и как копируют...
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563245
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex KuznetsovЭто зависит от того чем и как копируют...Если файл не разреженный и чтение не посимвольное, то все прочие различия сильно нивелируются.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563299
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делали замеры - по разным языкам , платформам и средам java показывает один из самых плохих результатов :(
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563433
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1Делали замеры - по разным языкам , платформам и средам java показывает один из самых плохих результатов :(
Что с одной стороны - не удивительно (все же JRE частично интерпретатор), с другой стороны - при наличие желания , разница в скорости должна быть достаточно не большая и в большей мере лимитироваться скоростью чтения с диска (JIT)

Да и вообще, задача считать много миллионно строковый файл с максимальной скоростью - выглядит немного странно.

Если его нужно считывать все время - нафига? почему такой не удобный формат?
если при загрузки приложения - то +/- пара секунд большого значения иметь не должно
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563493
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Atum1,
Код: java
1.
2.
3.
4.
5.
        while ((str = in.readLine()) != null) {
            String arr[] = str.split("\t");
            rlst = new ArrayList<String>(Arrays.asList(arr));
            list.addLast(rlst);
        }


1000000 строк - 1000000 раз будет создаваться и компилироваться Pattern, скорее всего, можно ускорить разбор, заготовив Pattern заранее. Еще быстрее - искать индекс символа '\t' с помощью метода String.indexOf(ch, fromIndex), чтобы не городить паттерн из-за одного символа.
Ну и с доступом к файлу, меппинг в память (MappedByteBuffer) - правильное направление, это действительно самый быстрый способ, так сказать, буферизация средствами ОС, но со строками придется повозиться
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563499
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проверил на JDK 7 c nio
Для простоты заменил ArrayList<String> на Bill (простой класс с полями под строку name1\tname2\tname3\tname4\tname5)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public class NioReader {

    public static void main(String[] args) throws IOException {
        long time = System.currentTimeMillis();
        ArrayList<Bill> list = new ArrayList<Bill>(1000010);
        BufferedReader rdr = Files.newBufferedReader(Paths.get("in.txt"), Charset.defaultCharset());
        rdr.readLine();
        for (String line; (line = rdr.readLine()) != null;) {
            list.add(new Bill(line));
        }

        long t1 = System.currentTimeMillis() - time;
        System.out.println(" read file " + (t1) + " ms");

        rdr.close();
    }
}


время 2.7 секунды


При переходе на JDK 8 стабильно +1 секунда и время хуже чем в JDK 6 (порядка 3 секунд).
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563587
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если нужна скорость:
1. Если чтение информации многократное, хранить в нормальном формате. Не текстовый, а нормальный двоичный формат
2. Нафиг ООП
3. Нормально профилировать приложение, а не мерить диаметр сферического коня (subj) в вакууме. Куда у Вас уходит время, только Вам и известно: толи ввод/вывод, толи выделение памяти под не нужное ООП, толи GC, толи в LinkedList.
etc...

IMHO & AFAIK

Ради интереса:
1. сколько полей в одной строке файла
2. какой размер файла в байтах
3. какой размер отдельных полей

Только сейчас написал простенький тест на Java. Если не заниматься фигней (типа универсальным преобразованием из любой кодовой таблицы в/из UTF8, ООП и прочее) скорость Java не настолько уж и плохая ))) по крайней мере на моем рабочем компе )))
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563588
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1, в идеальном варианте ты делаешь 2 потока. 1-й читает блоками char[] и пишет в кольцевую память.
2-й поток - конечный автомат (Finite-state_machine) который разбирает эти блоки и генерирует евенты.
Например - 'onBeginBackslashSymbol'. И соотв. принимает какие-то решения.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563591
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mayton, там еще на преобразование charset время уходит дофига. Скорее всего.

А с учетом много-символьных MBCS задача организовать кольцевой буфер будет не сильно простая. Лично я бы упрощал задачу. Нафиг все много-символьные MBCS. IMHO.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563596
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На моем компе только чтение из файла размером 163 Mb:

read binary - 54 ms. (ручками)
read text - 3906 ms. (через java.io.Reader)

При ограничении charset'ов только однобайтовыми наборами, легко можно читать и парсить в несколько потоков. Но при многобайтовых MBCS, задача скорее всего усложнится IMHO & AFAIK. Как минимум нужно книжки читать (я не настолько хорошо знаю принципы организации многобайтовых MBCS) и реализацию Charset и Reader смотреть.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563599
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevMayton, там еще на преобразование charset время уходит дофига. Скорее всего.

Вот это коментарий в точку.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563600
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev, потесть пожалуйста utf-8, utf-16, и однобайтовые.
Я думаю что utf-8 должен иметь самый хардкорный char-decoder. Фактически
дезархиватор мать его так.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563609
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема не в хардкордном. А то, что все интерфейсы сделаны универсальными и ООП'ыми.

Соответственно, Charset при декодировании вынужден порождать кучу вспомогательных буферов и отслеживать движение вперед/назад по потоку. IMHO & AFAIK Думаю, разницы в скорости реализации стандартных декодеров Charset большой нет. Даже тестить не охота. Проблема не в конкретном charset, а в _универсальности_ стандартных реализаций.

Если же ОГРАНИЧИВАТЬ исходную задачу, то тогда можно сделать быстрое решение. Если же делать УНИВЕРСАЛЬНОЕ решение, то нефиг на Java поклеп возводить. Плата за универсальность и поддержку кучи Charset.

Но судя по постам автора - а оно на форуме надо? решать дебильную по постановке задачу и заниматься оптимизацией. В принципе, такая работа как оптимизация бизнес-критикал кусков кода IMHO & AFAIK очень дорого стоит.

К тому же, совершенно не понятно. ЗАЧЕМ это нужно. Один раз считать файл при загрузки приложение, что 0.5 сек, что 5 сек - роли большой иметь не должно. Нужна сверх скорость (близкая к ассемблеру) - перерабатывать постановку, делать нормальные форматы хранения данных и на диске и в памяти. Загонять миллионы объектов в LinkedList лично мне Java'у было бы жалко ))) Но я программировать учился на 286 с 1 Mb ОП и там ГИС писал (ГеоИнформационная система), т.ч. уже при словах LinkedList, миллион объектов мне компьютер и процессор жалко становится. Жалостливый я очень ))).
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563627
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сишники хардкодили char как byte. Это в 99% случаев решало проблемы перекодировок. И парсеры
работали с байтами. Но эпоха 1-byte ушла. А Unicode так и не зохватила вселенную. Вот и сидим
на двух стульях. Внутри БД Oracle до сих пор рулит 1251 ибо быстро и нефих.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563669
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonСишники хардкодили char как byte. Это в 99% случаев решало проблемы перекодировок. И парсеры
работали с байтами. Но эпоха 1-byte ушла. А Unicode так и не зохватила вселенную. Вот и сидим
на двух стульях. Внутри БД Oracle до сих пор рулит 1251 ибо быстро и нефих.Вот и я о том, нефиг заниматься мазохизмом пытаясь выжать из тройного разбора строк скорость. Хоть все соки выжми - нифига хорошего не выйдет. Проход по файлу и по считанному буферу должен быть всего один. И именно за один проход нужно строить весь список, а не херячить по буферу в поисках строк с помощью ReadLn, затем выпендриваться с вызовом split, наконец всё это зафигачивать в ArrayList и только потом этот ArrayList запендюривать в LinkedList... Файл должен рассматриваться как набор байт с двумя типами разделителей и фсё...
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563701
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня.

Файл миллион строк, 50 колонок, размер 421 Mb

Изначальная автора: от 2 259 до 5 807 ms
Моя реализация - от 13 262 до 14 849 ms

Моя реализация, парсинг плюс перегон в String[] (без построения LinkedList) - 3 444
Моя реализация, чтение файла + конвертация charset + парсинг онли - 1 575
Моя реализация, чтение файла + конвертация charset only - 228 ms

(((

Почему кусок кода построения LinkedList, вставленный без изменения в мой алгоритм, настолько резко начинает тормозит. Мне не понятно. Шаманство.

Код: java
1.
2.
3.
       ArrayList<String> rlst = null;
       rlst = new ArrayList<String>(Arrays.asList(arr));
       list.addLast( rlst );
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563707
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev, запускай профилировщик.
...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563710
avp.mk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsevтам еще на преобразование charset время уходит дофига. Скорее всего.
Да не особо.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
700 000 слов (Windows 1251; 14,6Mb)
readBytes : 504.558745ms
readChars : 683.095014ms

700 000 слов (UTF-8; 17,9Mb)
readBytes : 664.528306ms
readChars : 713.824252ms


10 000 000 слов (Windows 1251; 220Mb)
readBytes :  8152.754886ms
readChars : 10974.168491ms

10 000 000 слов (UTF-8; 266Mb)
readBytes :  9415.190546ms
readChars : 10618.989616ms



Генератор
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
package textgen;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Random;

public class TextGen {

    private static final String PATH_SRC = "C:\\Documents and Settings\\User\\Рабочий стол\\src.txt";

    public static void main(String[] args) throws IOException {
        try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(PATH_SRC), "Cp1251"))) {
            Random r = new Random();
//            for (int i = 1; i < 2_000_001; ++i) { //450Mb
//            for (int i = 1; i < 1_000_001; ++i) { //220Mb
            for (int i = 1; i < 70_001; ++i) { //14Mb
                for (int j = 0; j < 10; ++j) {
                    writer.write("слово_");
                    writer.write(Integer.toString(i));
                    writer.write('_');
                    for (int k = 7 + r.nextInt(5); k > 0; --k) {
                        writer.write('a' + r.nextInt(25));
                    }
                    writer.write('\t');
                }
                writer.write('\n');
            }
        }
    }
}

ReadFile.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
package readfile;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;

import static java.lang.System.*;
import static java.util.Arrays.copyOf;

public class ReadFile {

    /** максимальная длина слова */
    private static final int BUFFER_SIZE = 64_000;
    private static final String
            CHARSET  = "Cp1251",
//            CHARSET  = "UTF-8",
            PATH_SRC = "C:\\Documents and Settings\\User\\Рабочий стол\\src.txt";

    public static void main(String[] args) throws IOException {
//        readBytes();
        readChars();
    }

    private static void readChars() throws IOException {
        long time = nanoTime();

        ArrayList<String> arrayList;
        try (Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(PATH_SRC), CHARSET))) {
            arrayList = new ArrayList<>(700_000);
//            arrayList = new ArrayList<>(10_000_000);
//            arrayList = new ArrayList<>(20_000_000);
            int position = 0;
            char[] buffer = new char[BUFFER_SIZE];
            for (int readed; (readed = reader.read()) != -1;) {
                if (readed > 32) {
                    buffer[position++] = (char) readed;
                } else if (position > 0) {
                    arrayList.add(new String(buffer, 0, position));
                    position = 0;
                }
            }
        }

        time = nanoTime() - time;
        out.println(arrayList.size() + " слов");
        out.println("readChars : " + time / 1e6 + "ms");
    }

    private static void readBytes() throws IOException {
        long time = nanoTime();

        ArrayList<byte[]> arrayList;
        try (InputStream reader = new BufferedInputStream(new FileInputStream(PATH_SRC))) {
            arrayList = new ArrayList<>(700_000);
//            arrayList = new ArrayList<>(10_000_000);
//            arrayList = new ArrayList<>(20_000_000);
            int position = 0;
            byte[] buffer = new byte[BUFFER_SIZE];
            for (int readed; (readed = reader.read()) != -1;) {
                if (readed > 32) {
                    buffer[position++] = (byte) readed;
                } else if (position > 0) {
                    arrayList.add(copyOf(buffer, position));
                    position = 0;
                }
            }
        }

        time = nanoTime() - time;
        out.println(arrayList.size() + " слов");
        out.println("readBytes : " + time / 1e6 + "ms");
    }
}

...
Рейтинг: 0 / 0
Быстрое чтение и разбор файла
    #38563718
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevУ меня.

Файл миллион строк, 50 колонок, размер 421 Mb

Изначальная автора: от 2 259 до 5 807 ms
Моя реализация - от 13 262 до 14 849 ms

Моя реализация, парсинг плюс перегон в String[] (без построения LinkedList) - 3 444
Моя реализация, чтение файла + конвертация charset + парсинг онли - 1 575
Моя реализация, чтение файла + конвертация charset only - 228 ms

(((

Почему кусок кода построения LinkedList, вставленный без изменения в мой алгоритм, настолько резко начинает тормозит. Мне не понятно. Шаманство.

Код: java
1.
2.
3.
       ArrayList<String> rlst = null;
       rlst = new ArrayList<String>(Arrays.asList(arr));
       list.addLast( rlst );



На этом месте у меня так же наблюдается сильное падение - фактически 50% от общего времени !
Первое что приходит - большие накладные расходы - на ArrayList - и LinkedList

пытался их оптимизировать - ставя размеры итд ...

видимо нужно отказываться от такого формата . переходить на простые массивы или читать
как описали -в буфер а уже его парсить.

Давайте выкинем ArrayList и LinkedList и просто разберемся с чтение файла по строкам!

Да за ООП - приходиться много платить и за весь стек интерфейсов и абстракций и всему должно быть объяснение ,

но не в секунды , когда тот же awk - делает эту же задачу на порядок быстрее!
...
Рейтинг: 0 / 0
25 сообщений из 158, страница 1 из 7
Форумы / Java [игнор отключен] [закрыт для гостей] / Быстрое чтение и разбор файла
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]