Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ? / 25 сообщений из 29, страница 1 из 2
18.04.2013, 10:00:19
    #38230301
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Здравствуйте.

Дано:
1) файл с 10 млн строками, в каждой - int-число; скачать его можно тут: http://ge.tt/5LUt8Oe/v/0
2) класс с единственной String-переменной, считывающий в неё каждую строку этого файла:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
import java.io.*;
public class MemoConsumptionExplore1 {
    public static void main(String[] args) throws IOException {
        new MemoConsumptionExplore1().run();
    }
    void run() throws IOException {
        String file = "c:\\java_test_int_1e7.txt";
        BufferedReader fr=new BufferedReader(new FileReader(file));
        String s;
        while ( fr.ready() ) {
            s = fr.readLine();
        }
    }
}



Профайлинг этого класса показывает, что used heap превышал 5 мегов, а для размещения 10 млн char[]-объектов потребовалось более 42 Мб (см аттач).
Объясните, плз: он что, для каждой прочитанной строки создаёт новый char[] ? Откуда эти сумасшедшие цифры взялись, чтобы прочесть всего 10 млн строк, причём в одну и ту же переменную ?...
...
Рейтинг: 0 / 0
18.04.2013, 10:07:11
    #38230315
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
String - immutable тип. Каждая новая строка это новый объект памяти. При чем тут вообще переменная? Переменная это лишь ссылка на объект. Поэтому текст нужно обрабатывать поточно это раз. Если файл это не текст, а числа, то и вычитывать его лучше как числа, это два.
...
Рейтинг: 0 / 0
18.04.2013, 10:22:34
    #38230338
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
BlazkowiczString - immutable тип. Каждая новая строка это новый объект памяти. При чем тут вообще переменная? Переменная это лишь ссылка на объект. Поэтому текст нужно обрабатывать поточно это раз. Если файл это не текст, а числа, то и вычитывать его лучше как числа, это два.Про immutable - спасибо, понял.
Только не ясно, как вообще заставить его поменьше обжорствовать.
Если так:
Код: java
1.
2.
3.
4.
5.
6.
...
        StringBuilder b;
        while ( fr.ready() ) {
            b = new StringBuilder(fr.readLine());
        }
        ...

- то еще хуже, 118 Мб.
Как правильно делать ?
И еще: "текст нужно обрабатывать поточно " - что это даст, меньше памяти будет жрать ?
(в файле могут быть не только int-числа, это всего лишь для примера)
...
Рейтинг: 0 / 0
18.04.2013, 10:26:37
    #38230344
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosisТолько не ясно, как вообще заставить его поменьше обжорствовать.

Не понятна постановка задачи. Вычитать 10млн строк в память? Ну, вы это и получили. Больше ничего этот код не делает.
...
Рейтинг: 0 / 0
18.04.2013, 10:29:20
    #38230352
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Добрый день, ozzmosis!

> Профайлинг этого класса показывает, что used heap превышал 5 мегов, а
> для размещения 10 млн char[]-объектов потребовалось более 42 Мб (см аттач).
> Объясните, плз: он что, для каждой прочитанной строки создаёт новый
> char[] ? Откуда эти сумасшедшие цифры взялись, чтобы прочесть всего 10
> млн строк, причём в одну и ту же переменную ?...

А в чём вообще проблема?

JVM дали памяти. Она ей распоряжается как хочет. Если места много-
сборка мусора откладывается. Надо будет- вернётся всё на место.

Можно попробовать поставить -xMx=32m или что-нибудь в этом роде, и
посмотреть.

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.04.2013, 10:32:01
    #38230356
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosis,

fr.readLine() не используйте вообще.
Используйте fr.read(buffer...)
где buffer это char[], тогда у вас не будет каждый раз создаваться строка, а будет каждый раз наполнятся один и тот же массив.

Если вы что-то парсите, то не понятно, почему не взять готовые библиотеки.
...
Рейтинг: 0 / 0
18.04.2013, 10:32:24
    #38230357
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
BlazkowiczozzmosisТолько не ясно, как вообще заставить его поменьше обжорствовать.

Не понятна постановка задачи. Вычитать 10млн строк в память? Ну, вы это и получили. Больше ничего этот код не делает.Дык я специально упростил всё. Конечно же, дальше я что-то буду делать с каждой из прочитанных строк. Например, если она состоит из строго двух слов, то добавлю в предв. созданный HashMap, если из одного в - HashSet, если из трёх и более - в игнор её, и т.д.
Я просто пока хочу понять, как сделать "вычитку" файла с минимальными затратами по памяти (файл, есс-но, гораздо больше, чем эти 10 млн строк).
...
Рейтинг: 0 / 0
18.04.2013, 10:37:14
    #38230365
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosisДык я специально упростил всё. Конечно же, дальше я что-то буду делать с каждой из прочитанных строк. Например, если она состоит из строго двух слов, то добавлю в предв. созданный HashMap, если из одного в - HashSet, если из трёх и более - в игнор её, и т.д.
Я просто пока хочу понять, как сделать "вычитку" файла с минимальными затратами по памяти (файл, есс-но, гораздо больше, чем эти 10 млн строк).
Сведите использование String к минимуму.
Читайте через переиспользуемый char[] буфер.
Местами String можно заменить на CharSequence.
...
Рейтинг: 0 / 0
18.04.2013, 10:38:28
    #38230368
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Blazkowicz fr.readLine() не используйте вообще.
Используйте fr.read(buffer...)
где buffer это char[], тогда у вас не будет каждый раз создаваться строка, а будет каждый раз наполнятся один и тот же массив.

Если вы что-то парсите, то не понятно, почему не взять готовые библиотеки.Ясно, спасибо вам еще раз.

Да, и еще вопрос, в догонку.
Есть у мну переменная b1 типа BigInteger.
Есть файл, все строки которого - только числа, но весьма большие.
Как внутри цикла присваивать переменной b1 очередное прочитанное число, но чтобы не создавать строку с передачей конструктору BigInteger(String val) ?
В конструкторах BigInteger нету такого, которому аргументом можно передать char[]. Там есть BigInteger(byte[] val), но я не въехал, что ему надо подсовывать. Двоичное представление прочитанного числа ? Ну так я еще не знаю его Bigint-значения.
...
Рейтинг: 0 / 0
18.04.2013, 10:44:27
    #38230382
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Кстати, сразу бросается в глаза StringBuffer на 4 месте. Хотя мог бы быть StringBuilder. Эх, не экономят время процессора при чтении файла
...
Рейтинг: 0 / 0
18.04.2013, 11:02:35
    #38230424
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ivanraКстати, сразу бросается в глаза StringBuffer на 4 месте. Хотя мог бы быть StringBuilder. Эх, не экономят время процессора при чтении файла
В Java 7 особой разницы уже нет. Если StringBuffer использутеся одним потоком, затраты на synchronized не значительны.
...
Рейтинг: 0 / 0
18.04.2013, 11:10:04
    #38230445
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosisЕсть у мну переменная b1 типа BigInteger.
Есть файл, все строки которого - только числа, но весьма большие.
Как внутри цикла присваивать переменной b1 очередное прочитанное число, но чтобы не создавать строку с передачей конструктору BigInteger(String val) ?
В конструкторах BigInteger нету такого, которому аргументом можно передать char[]. Там есть BigInteger(byte[] val), но я не въехал, что ему надо подсовывать. Двоичное представление прочитанного числа ? Ну так я еще не знаю его Bigint-значения.
Здесь уже надо пробовать и смотреть. BigInteger API что-то не проапдейтили для этих целей. Сначала попробуйте создавать String непосредственно из char[] полного числа. И посмотреть на сколько это приемлемое для вас решение. Если нет, тогда уже можно искать обходные пути.
...
Рейтинг: 0 / 0
18.04.2013, 11:24:00
    #38230480
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Добрый день, Blazkowicz!

> Здесь уже надо пробовать и смотреть. BigInteger API что-то не
> проапдейтили для этих целей.

Как это? Там конструктор есть
public BigDecimal(char[] in, int offset, int len)

Дочитать его до конца у меня сил не хватило :) но вроде как строк не
создаётся.

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.04.2013, 11:25:16
    #38230483
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
GKS_SamaraКак это? Там конструктор есть
public BigDecimal(char[] in, int offset, int len)

В BigInteger - нет.
...
Рейтинг: 0 / 0
18.04.2013, 11:25:46
    #38230486
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Добрый день!

>> Здесь уже надо пробовать и смотреть. BigInteger API что-то не
>> проапдейтили для этих целей.
>
> Как это? Там конструктор есть
> public BigDecimal(char[] in, int offset, int len)
>
> Дочитать его до конца у меня сил не хватило :) но вроде как строк не
> создаётся.

Блин, не заметил- это ж BigDecimal. У BigInteger такой конструктор
уровня пакета.


--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.04.2013, 11:27:14
    #38230488
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
GKS_SamaraБлин, не заметил- это ж BigDecimal. У BigInteger такой конструктор
уровня пакета.

Но топикастеру стоит попробовать BigDecimal, как вариант. Возможно разницы с BigInteger особой не будет.
...
Рейтинг: 0 / 0
18.04.2013, 13:24:56
    #38230798
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosisЕсли так:
Код: java
1.
2.
3.
4.
5.
6.
...
        StringBuilder b;
        while ( fr.ready() ) {
            b = new StringBuilder(fr.readLine());
        }
        ...

- то еще хуже, 118 Мб.
Как правильно делать ?

А зачем вы создаете каждый раз при чтении строки новый StringBuilder? Почему не как-то так?
Код: java
1.
2.
3.
4.
5.
6.
        StringBuilder b;
        b = new StringBuilder(1000000); //1000000 для примера, можно прикинуть, сколько выделить, 
       //чтобы меньше потом перевыделять память
        while ( fr.ready() ) {
            b.append(fr.readLine());
        }


(С Java не особо знаком, может я чего-то не понял).
...
Рейтинг: 0 / 0
18.04.2013, 13:31:36
    #38230807
s62
s62
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
А, понял кажется, это у вас просто тест, просто считываете отдельно каждую строку.
...
Рейтинг: 0 / 0
18.04.2013, 13:39:39
    #38230818
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Blazkowicz,

спасибо за ответы. Буду пробовать.
...
Рейтинг: 0 / 0
18.04.2013, 17:24:15
    #38231364
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Нет, не могу осилить что-то этот самый "потоковый ввод".

Вот есть код, генерящий (для примера) 10 bigint-чисел и записывающий их в файл.
Затем этот файл считывается и для каждого числа надо определить, простое оно или нет (с некоторой вероятностью).
Далее сложить только простые числа в HashSet и вывести общее их кол-во:
Код: 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.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class FileReaderTest {
    StreamTokenizer in;
    BufferedWriter bw;
    final String FILE_NAME="c:\\bigints.txt";
    public static void main(String[] args) throws IOException {
        new FileReaderTest().run();
    }
    void run() throws IOException {
        bw = new BufferedWriter(new FileWriter(FILE_NAME));
        int N = 10; // 000;
        BigInteger b;
        Random r = new Random();
        for (int i = 0; i < N; i++) {
           b = new BigInteger(128, r);
           bw.write(b.toString());
           bw.newLine();
        }
        bw.close();        
        //---------------------------------------------------------------------
        in = new StreamTokenizer(new BufferedReader(new FileReader(FILE_NAME))); 
        
        HashSet<BigInteger> hsPrimes = new HashSet<BigInteger>();
        int i=0;
        BigInteger p;
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            // ? how to cast next token as String ?
            //p.isProbablePrime(4);
            i++;
        }
        System.out.println("total primes in list: "+i);
    }
} // end of class FileReaderTest



ВОПРОС. Как заставить StreamTokenizer при чтении ЧИСЛА (127776541237890123 etc - явно большего, чем MAX_INT) воспринять прочитанное как СТРОКУ, чтобы на основе её создать новый BigInt-объект ? ПоможЫте, плз :-/
...
Рейтинг: 0 / 0
18.04.2013, 17:36:41
    #38231401
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
всё время читать как строку tokenizer.sval
...
Рейтинг: 0 / 0
18.04.2013, 17:40:09
    #38231409
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Blazkowiczвсё время читать как строку tokenizer.svalДык! Пробовал, разумеется.
Вот:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
...
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            // ? how to cast next token as String ?
            String s = in.sval;
            System.out.println("s="+s);
            p=new BigInteger(s);
            //p.isProbablePrime(4);
            i++;
        }

Результат:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
run:
s= null  
Exception in thread "main" java.lang. NullPointerException
	at java.math.BigInteger.<init>(BigInteger.java:271)
	at java.math.BigInteger.<init>(BigInteger.java:451)
	at DataStructures.FileReaderTest.run(FileReaderTest.java:33)
	at DataStructures.FileReaderTest.main(FileReaderTest.java:10)
Java Result: 1
...
Рейтинг: 0 / 0
18.04.2013, 17:49:41
    #38231426
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosis,

Код: java
1.
2.
3.
if(s == null){
  continue;
}
...
Рейтинг: 0 / 0
18.04.2013, 18:00:41
    #38231443
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Blazkowiczozzmosis,

Код: java
1.
2.
3.
if(s == null){
  continue;
}


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
        int i=0;
        BigInteger p;
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            // ? how to cast next token as String ?
            String s = in.sval;
            if (s==null) {
                continue;
            }
            System.out.println("s="+s);
            p=new BigInteger(s);
            //p.isProbablePrime(4);
            i++;
        }
        System.out.println("total primes in list: "+i);



Однако:
Код: plaintext
1.
2.
run:
total primes in list: 0
BUILD SUCCESSFUL (total time: 0 seconds)

То есть, он (in.sval) вообще ни одно из BigInteger -чисел не обработал, всё воспринял как null.
...
Рейтинг: 0 / 0
18.04.2013, 20:28:25
    #38231640
ozzmosis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
ozzmosisТо есть, он (in.sval) вообще ни одно из BigInteger -чисел не обработал, всё воспринял как null.ффух, нашёл. Ему (объекту StreamTokenizer'a) надо "прочистить мозги", вызвав resetSyntax(), wordChars('0', '9') и whitespaceChars('\r', '\r'). Только тогда он начнёт считываемые числа считать строками, и их можно будет уже подсовывать в конструктор BigInteger'a.
Код: 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.
import java.io.*;
import java.math.BigInteger;
import java.util.*;
public class FileReaderTest {
    StreamTokenizer in;
    BufferedWriter bw;
    final String FILE_NAME="c:\\bigints.txt";
    public static void main(String[] args) throws IOException {
        new FileReaderTest().run();
    }
    void run() throws IOException {
        bw = new BufferedWriter(new FileWriter(FILE_NAME));
        int N = 1000;
        BigInteger b;
        Random r = new Random();
        for (int i = 0; i < N; i++) {
           b = new BigInteger(164, r);
           bw.write(b.toString());
           bw.newLine();
        }
        bw.close();        
        //---------------------------------------------------------------------
        in = new StreamTokenizer(new BufferedReader(new FileReader(FILE_NAME))); 

        // commands to handle result of in.sval always as String 
        // during read of large integer numbers:
        in.resetSyntax();
        in.wordChars('0', '9');
        in.whitespaceChars('\r', '\r');
        in.whitespaceChars('\n', '\n');
        
        TreeSet<BigInteger> hsPrimes = new TreeSet<BigInteger>();
        int i=0;
        BigInteger p;
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            String s = in.sval;
            p=new BigInteger(s);
            if (p.isProbablePrime(4)) {
                hsPrimes.add(p);
                i++;
            }
        }
        
        for( BigInteger hsx : hsPrimes ) {
            System.out.println(hsx);
        }
        System.out.println("\nTotal primes in list: "+i);
    }
} // end of class FileReaderTest


Пример результата:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
run:
4612619974923713006482770328350670622019371639077
7189510052098150038091299601582044773577185859157
8407730875700650704020123844924590906417514732821
8867142705835293079085585841666931214505993454957
10354240823379391054805894162827628843337663603409
17142209726205277927415048885733089334431596809097
22323063444758797701968114793566179667817460514761
23159319033082054596615693780239344377534899380351

Total primes in list: 8
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ? / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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