среда, 4 апреля 2012 г.

Ввод и вывод. Файл и консоль

Для начала поговорим о выводе данных.
Давайте рассмотрим всем известный способ вывода данных, а именно:
System.out.println("123");
Окей. А теперь давайте посмотрим на класс java.io.PrintWriter. Выведем 1 000 000 чисел на экран и засечем время работы.
import java.io.*;

public class Temp {
    public static void main(String[] args){
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));
        int n = 1000*1000;
        long time = System.currentTimeMillis();
        for (int i = 0; i < n; ++i)
            writer.print(i + " ");
        writer.println();
        writer.println(System.currentTimeMillis()-time);
        writer.close();
    }
}
На моём компьютере результат получается равным примерно 1000-1100 мс. У вас может получится другое число. А теперь попробуем сделать тоже самое с помощью System.out.

public class Temp {
    public static void main(String[] args){
        int n = 1000*1000;
        long time = System.currentTimeMillis();
        for (int i = 0; i < n; ++i)
            System.out.print(i + " ");
        System.out.println();
        System.out.println(System.currentTimeMillis()-time);
    }
}
У меня получилось около 4500 мс. Чувствуете разницу? Чтобы использовать PrintWriter понадобилось добавить всего 2 строчки, а какой прирост скорости!
Для записи в файл используйте FileOutputStream :
PrintWriter writer = new PrintWriter(new FileOutputStream("output.txt"));
И да, не забудьте обработать IOException.
Будем считать, что с выводом мы разобрались.
Если для вас важны скорость и удобство вывода - используйте PrintWriter.
Теперь разберемся с вводом.
Для ввода есть очень удобный класс java.util.Scanner. Итак, давайте попробуем прочитать с помощью него всё те же 1 000 000 чисел из файла.
import java.io.*;
import java.util.Scanner;

public class Temp {
    public static void main(String[] args) throws IOException{
        Scanner sc = new Scanner(new File("output.txt"));
        int n = 1000*1000;
        int x;
        long time = System.currentTimeMillis();
        for (int i = 0; i < n; ++i)
            x = sc.nextInt();
        System.out.println(System.currentTimeMillis()-time);
    }
}
У меня время работы получается равным примерно 1800 мс. Попробуем улучшить этот результат, правда теперь кода придется добавить побольше. Используем java.io.BufferedReader.
import java.io.*;
import java.util.StringTokenizer;

class MyReader{
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;
    MyReader(Reader r) throws IOException{
        reader = new BufferedReader(r);
    }
    public int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }
    public String nextToken() throws IOException {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(reader.readLine());
        }
        return tokenizer.nextToken();
    }
}

public class Temp {
    public static void main(String[] args) throws IOException{        
        MyReader reader = new MyReader(new FileReader("output.txt"));
        int n = 1000*1000;
        int x;
        long time = System.currentTimeMillis();
        for (int i = 0; i < n; ++i)
            x = reader.nextInt();
        System.out.println(System.currentTimeMillis()-time);
    }
}
Время работы на моём компьютере около 300 мс! По аналогии с методом nextInt() можно добавить методы и для остальных типов и будет прямо как Scanner. Только работать будет в разы быстрее. ;)
Для ввода из консоли используйте:
MyReader reader = new MyReader(new InputStreamReader(System.in));
Нужна хорошая скорость ввода - BufferedReader вам в помощь!
Надеюсь кому-нибудь это пригодится.
Удачи!

Комментариев нет:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.