LoginSignup
0
1

More than 3 years have passed since last update.

JavaのScannerはどれほど遅いのか?

Posted at

こちらでJavaのScannerが非常に遅いと言う話題が出たので、どれぐらい遅いか測ったので簡単に報告です。

Python, Java, C++の速度比較

結果

data数=100万 実行時間
JavaのScanner 714 msec
自前Scanner 24 msec
倍率 29.75

自前の簡素なScannerに比べて、JavaのScannerは、だいたい30倍近い時間がかかってます。
競技プログラミングではSannerは使わない方が良さそうですね。

以下に比較に使ったコードを載せます。

JavaのScannerをそのまま使った版

import java.util.*;
import java.io.*;
import java.util.stream.*;

public class ScannerTest {
    public static void main(String[] args) {
        long t0 = System.currentTimeMillis();
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] d = new int[n];
        for (int i = 0; i < n; i++) {
            d[i] = sc.nextInt();
        }
        long t1 = System.currentTimeMillis();
        System.out.println("n = " + n );
        System.out.println((t1-t0) + " msec");
        int sum = IntStream.of(d).sum();
        System.out.println("sum = " + sum);
    }
}

自前のなんちゃってint値読み込みScanner版

import java.util.*;
import java.io.*;
import java.util.stream.*;

public class ScannerTest3 {
    static class MyScanner {
        byte[] bytes;
        int pos = 0;
        int len;
        InputStream inputStream;
        MyScanner(InputStream is){
            try{
                inputStream = is;
                bytes = new byte[1024];
                len = Math.max(0,inputStream.read(bytes));
                pos = 0;
                return;
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        private byte getNextByte() throws IOException {//throws ArrayIndexOutOfBoundsException
            if( pos >= len ){
                len = Math.max(0,inputStream.read(bytes));
                pos = 0;
            }
            byte result = bytes[pos++];
            return result;
        }
        int nextInt() throws IOException {
            int result = 0;
            byte v;
            while(true){
                v = getNextByte();
                if( v != ' ' && v != '\n' && v != '\r'){
                    break;
                }
            }
            while(true){
                if( v == ' ' || v == '\n' || v == '\r' ){
                    break;
                }
                result *= 10;
                result += (int)v - (int)'0';
                v = getNextByte();
            }
            return result;
        }
    }
    public static void main(String[] args) throws Exception{
        long t0 = System.currentTimeMillis();
        MyScanner sc = new MyScanner(System.in);
        int n = sc.nextInt();
        int[] d = new int[n];
        for (int i = 0; i < n; i++) {
            d[i] = sc.nextInt();
        }
        long t1 = System.currentTimeMillis();
        System.out.println("n = " + n );
        System.out.println((t1-t0) + " msec");
        int sum = IntStream.of(d).sum();
        System.out.println("sum = " + sum);
    }
}
0
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1