powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
4 сообщений из 29, страница 2 из 2
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
    #38231708
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczozzmosis,

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

Если вы что-то парсите, то не понятно, почему не взять готовые библиотеки.Теперь осталось понять, как юзать BufferedReader вкупе с char[], чтобы читать строки, разделенные символами перевода строки, каждый раз в один и тот же char[].
Но поскольку у мну обработка больших чисел, надо этот chr[]-массив после считывания в него символов как-то обработать, чтобы его смог съесть конструктор BigDecimal.

Код: java
1.
2.
3.
4.
5.
        br = new BufferedReader(new FileReader(FILE_NAME));
        char[] buf = new char[60]; // 60 = гарантированно больше, чем число десятичных знаков в сгенерённых BigInt-числах
        while (br.ready()) {
            // br.read(buf, off, len); // вот тут - что надо делать ?
        }


Что следует делать / вызвать там, внутри цикла ? Он же считывает каждый байт, в том числе переводы строк.
Надо как-то "эмулировать" readline(), чтобы при чтении ограничивался каждый раз символом CR/LF.
Попробовал велосипед сделать, получилась неработающая туфта:
Код: 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.
        br = new BufferedReader(new FileReader(FILE_NAME));
        char[] buf = new char[60];
        int k=0;
        List clist;
        //System.out.println(br.markSupported());
        BigDecimal d;
        while (br.ready() && k<10) {
            br.mark(60);
            br.read(buf, 0, 60);
            int crlf=0;
            for (int j = 0; j < buf.length; j++) {
                if (buf[j]=='\r') {
                    crlf=j;
                }
                if (j>=crlf-1) {
                    buf[j]=' ';
                }
            }
            br.reset();
            br.read(buf, 0, crlf);
            System.out.println((new String(buf)));
            d=new BigDecimal(buf);
            k++;
        }

Результат:
run:
Код: plaintext
1.
2.
3.
4.
5.
6.
100004163706653319627008032022914325716                     
Exception in thread "main" java.lang.NumberFormatException
	at java.math.BigDecimal.<init>(BigDecimal.java:459)
	at java.math.BigDecimal.<init>(BigDecimal.java:590)
	at DataStructures.ChkBigPrimes2.run(ChkBigPrimes2.java:48)
	at DataStructures.ChkBigPrimes2.main(ChkBigPrimes2.java:11)
Java Result: 1

Обламывается, видимо, на том, что в buf[] после цифр идут пробелы.
Велосипед изобретать глупо. Подскажите, плз - есть какие-то готовые решения для этого ?
...
Рейтинг: 0 / 0
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
    #38231901
ozzmosis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ozzmosisBlazkowiczozzmosis,

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

Если вы что-то парсите, то не понятно, почему не взять готовые библиотеки.Обламывается, видимо, на том, что в buf[] после цифр идут пробелы.
Велосипед изобретать глупо. Подскажите, плз - есть какие-то готовые решения для этого ?Ошибку победил, но судя по всему -коряво вышло :(
Нету выигрыша (я всё про объем памяти в профайлере).
Итак, два варианта чтения файла с BigInteger-числами, определения их простоты и укладывания по возрастанию в TreeSet (чтобы долго не ждать, ограничил чтение первыми 100 тыс сроками):
1. via StringTokenizer:
Код: 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.
import java.io.*;
import java.math.*;
import java.util.*;
// reading file with BigInts via StreamTokenizer + String handling
public class ChkBigPrimes {
    StreamTokenizer in;

    final String FILE_NAME="c:\\bigints.txt";
    final int MAX_LIMIT = 100000;
    public static void main(String[] args) throws IOException {
        new ChkBigPrimes().run();
    }
    void run() throws IOException {
        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>();
        BigInteger p;
        int i=0;
        while (in.nextToken() != StreamTokenizer.TT_EOF && i<MAX_LIMIT) {
            //p=new BigInteger(in.sval);
            p=new BigDecimal( (in.sval).toCharArray() ).toBigInteger();
            if (p.isProbablePrime(4)) {
                hsPrimes.add(p);
            }
            i++;
        }
        System.out.println("\nTotal primes in list: "+hsPrimes.size());
    }
} // end of class ChkBigPrimes


2. via BufferedReader + char[] + char[]: // да, ДВА char[]-массива
Код: 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.
import java.io.*;
import java.math.*;
import java.util.*;
// reading file with BigInts via BufferedReader + two char[] arrays
public class ChkBigPrimes2 {
    StreamTokenizer in;
    BufferedReader br;
    final String FILE_NAME="c:\\bigints.txt";
    final int CRLF_LENGTH=2;
    final int MAX_LIMIT = 100000;
    public static void main(String[] args) throws IOException {
        new ChkBigPrimes2().run();
    }
    void run() throws IOException {
        TreeSet<BigInteger> hsPrimes = new TreeSet<BigInteger>();
        br = new BufferedReader(new FileReader(FILE_NAME));
        char[] buf = new char[60];
        BigInteger p;
        int i=0;
        while (br.ready() && i<MAX_LIMIT) {
            br.mark(60);
            br.read(buf, 0, 60);
            int crlf_idx=0;
            for (int j = 0; j < buf.length; j++) {
                if (buf[j]=='\r') {
                    crlf_idx = j;
                }
            }

            char[] buf2 = new char[crlf_idx]; // пришлось создать второй char[],
            System.arraycopy(buf, 0, buf2, 0, crlf_idx); // т.к. не знаю, как по-другому вырезать из 1-го char[] часть его.

            br.reset();
            br.read(buf, 0, crlf_idx + CRLF_LENGTH);
            p=new BigDecimal(buf2).toBigInteger();
            if (p.isProbablePrime(4)) {
                hsPrimes.add(p);
            }
            i++;
        }
        br.close();
        System.out.println("\nTotal primes in list: "+hsPrimes.size());
    }
} // end of class ChkBigPrimes2



Оба варианта работают одинаково: на моей машине 14 сек.
И потребление памяти в обоих вариантах одинаковое - см скриншот.

И где тогда профит при отказе от readLine() ?
...
Рейтинг: 0 / 0
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
    #38237495
avp.mk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сколько этот?
LoadBigInteger
Код: 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.
package loadbiginteger;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashSet;
import java.util.Set;

public class LoadBigInteger {

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

    public static void main(String[] args) throws IOException {
        Set<BigInteger> hsPrimes = new HashSet<>();
        Reader in = new BufferedReader(new FileReader(PATH));
        char[] buffer = new char[1024 * 1024];

        int ch, position;
        do {
            position = 0;
            while (Character.isDigit(ch = in.read()) || ch == '-' || ch == '+') {
                buffer[position++] = (char) ch;
            }

            if (position > 0) {
                try {
                    BigInteger p = new BigDecimal(buffer, 0, position).toBigInteger();
//                    if (p.isProbablePrime(4)) { //эта функция работает основное время, имеет смысл распараллелить вычисление probablePrimes
                        hsPrimes.add(p);
//                    }
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }
            }
        } while (ch != -1);
        //разумеется ресурсы надо закрыть если программа ещё долго будет работать
        System.out.println("Total primes in list: " + hsPrimes.size());
    }
}


...
Рейтинг: 0 / 0
Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
    #38237510
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У этого файла такое жесткое форматирование что его можно считать двоичным типизированным.
Можно читать блоками по 14 CHARS и будет ОК. И диапазон long не превышает. Тут даже BitIneger
не нужно использовать.

Код: 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.
  1456996351
    58097664
   612630528
  1806270463
  1441398783
   491913216
  1446281215
  1231060991
  1776058367
  1763049471
   172097536
  1259208703
   235241472
  1604517887
   718635008
   853934080
   640548864
   783843328
  1944715263
    18546688
  2064646143
  1448280063
   863174656
  2048589823
   749404160
  1920303103
   122290176
  1490583551
  1931673599
  1216839679
  1068531712
  1655701503
   566132736
  1584562175
  2069364735
   236290048
   562397184
   562135040
  1354858495
  1322745855
  1684996095
...
Рейтинг: 0 / 0
4 сообщений из 29, страница 2 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Чтение 10 млн коротких строк (int-чисел) из файла. Как понять результаты профайлинга ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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