使用Java Scanner从控制台读取一个很长的字符串需要时间?

时间:2011-11-22 14:00:23

标签: java string long-integer java.util.scanner

目前我正在创建一个控制台程序,该程序使用非常长的String读取一行并使用java Scanner

样本数据更像是

一行中50000整数,由空格分隔,

"11 23 34 103 999 381 ....." until 50000 integer

此数据由用户通过控制台输入,而不是从文件

输入

这是我的代码

        System.out.print("Input of integers : ");
        Scanner sc = new Scanner(System.in);
        long start = System.currentTimeMillis();

        String Z = sc.nextLine();

        long end = System.currentTimeMillis();
        System.out.println("String Z created in "+(end-start)+"ms, Z character length is "+Z.length()+" characters");

然后我执行,结果我得到了这个

String Z created within 49747ms, Z character length is 194539 characters

我的问题是为什么需要很长时间? 有没有更快的方法来读取很长的字符串?

我尝试过缓冲读卡器,但差别不大......

String Z created within 41881ms, Z character length is 194539 characters

2 个答案:

答案 0 :(得分:2)

看起来扫描器使用正则表达式来匹配行尾 - 这可能导致效率低下,特别是因为你将正则表达式与200k长度的字符串匹配。

使用的模式实际上是。*(\ r \ n | [\ n \ r \ u \ u2028 \ u2029 \ u0085])|。+ $

答案 1 :(得分:0)

我的猜测是内存分配,因为它读取行,它填充char缓冲区。它变得越来越大,需要一次又一次地复制所有到目前为止的readed文本。每次它使内部缓冲区Ntimes更大,所以它不是非常慢,但对于你的大线,它仍然很慢。

处理regexp本身也没有用。但我的猜测是,重新定位和复制是减速的根源。

也许它需要做GC以释放内存来获取,所以另一个减速。

您可以通过复制扫描仪并将BUFFER_SIZE更改为等于您的线长(或更大,以确定)来测试我的假设。