java.util.Scanner是慢吗?

Cri*_*bie 16 java android

在Android应用程序中,我想使用Scanner类从文本文件中读取浮动列表(它是OpenGL的顶点坐标列表).确切的代码是:

Scanner in = new Scanner(new BufferedInputStream(getAssets().open("vertexes.off")));
final float[] vertexes = new float[nrVertexes];
for(int i=0;i<nrVertexFloats;i++){
    vertexes[i] = in.nextFloat();
}
Run Code Online (Sandbox Code Playgroud)

然而,似乎这是非常慢的(读取10,000个花车需要30分钟!) - 在2.1仿真器上进行测试.这是怎么回事?当我在PC上使用它时,我不记得Scanner是那么慢(事实上,我之前从未读过100多个值).或者是其他东西,比如从资产输入流中读取?

谢谢您的帮助!

Ian*_*son 22

正如其他海报所说,以二进制格式包含数据更有效.但是,为了快速修复,我发现更换:

scanner.nextFloat();
Run Code Online (Sandbox Code Playgroud)

Float.parseFloat(scanner.next());
Run Code Online (Sandbox Code Playgroud)

几乎快了7倍.

要向此答案添加更多信息,该方法的性能问题的根源是它使用正则表达式来搜索下一个浮点数,如果您事先知道要读取的数据的结构,则这是不必要的.

next*由于类似的原因,大多数(如果不是全部)使用正则表达式,所以如果你知道数据的结构,最好总是使用next()和解析结果.IE也使用Double.parseDouble(scanner.next())Integer.parseInt(scanner.next()).

相关来源:https: //android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/util/Scanner.java


Leo*_*nel 8

不了解Android,但至少在JavaSE中,Scanner很慢.

在内部,Scanner执行UTF-8转换,这在具有浮点数的文件中是无用的.

因为您要做的只是从文件中读取浮点数,所以您应该使用java.io包.

SPOJ的人们在I/O速度上挣扎.这是一个非常难的波兰编程竞赛网站.它们的不同之处在于它们接受比其他站点更广泛的编程语言,并且在许多问题中,输入非常大,如果您不编写高效的I/O,您的程序将突破时间限制.

例如,在这里查看他们的论坛,了解自定义解析器.

当然,我建议不要编写自己的浮点解析器,但如果你需要速度,那仍然是一个解决方案.

  • 看来Scanner在设备/模拟器上确实非常慢!这可能是因为内存分配数量巨大.在模拟器上,读取10,000个浮点数需要30分钟.在PC上需要1秒钟才能读取20,000个浮点数(使用扫描仪).作为一个解决方案,我发现以下工作非常好:首先我在PC上解析我的输入文件并将其转换为二进制数据,然后我逐字节地读取它(缓冲)并重建数字.这要快得多.读取20,000个花车需要1.5秒.我说这是1小时后的巨大进步:)感谢所有的帮助! (2认同)