2013-01-10 44 views
1

我想弄明白,如果有一种更快的方式从URL使用Scala获取内容。使用Apache IOUtils我能够在Scala中获得比Source.fromURL更快的内容。下面是从两个密码:为什么Scala Source.fromURL比Apaches IOUtils慢?

使用Java:

try { 
     tmp=IOUtils.toString(new URL("http://gizmodo.com")); 
     tmp=tmp.substring(tmp.indexOf("360\" title=")+12); 
     tmp=tmp.substring(0,tmp.indexOf("\"")); 
    } catch (MalformedURLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

使用斯卡拉:

val gizmodoPageLines = Source.fromURL("http://gizmodo.com").getLines.mkString("\n") 
    val pos=gizmodoPageLines.indexOf("360\" title=") 
    var tmp=gizmodoPageLines.substring(pos+12) 
    tmp.substring(0,tmp.indexOf("\"")) 

在Java约需:155899纳秒

在斯卡拉:343880纳秒

为什么Scala代码如此之慢?

+2

它真的让你花费数百秒来拉下gizmodo.com的首页内容? –

+0

你有没有试过[scala-io](http://jesseeichar.github.com/scala-io-doc/0.4.1/index.html#!/performance/Class-scalax.io.perf.channel.input。 SmallMediumSetsFromFileReadableByteChannelTest_Input-字节阵列)?该网站上有一些很好的性能数据。 – AmigoNico

回答

7

因为在你第一次读取缓冲区时,而在第二次读取时则逐行读取。

Source.getLines不能作为IOUtils或任何其他库的银色子弹替代品,它的目的是逐行阅读。您可以在Scala中完美使用IOUtils。

+0

更确切地说:Source.fromURL确实使用了缓冲区,但getLines输出了字符串,然后您使用mkString重新连接成一个字符串,而IOUtils.toString复制更大的块。 –

+0

关于你的数据和关于你的互联网连接的上述评论,你是否忘记提及你重复数千次? –

+0

+1,您可以在Scala中使用IOUtils:经过验证的可靠优化库。 Scala Source.fromURL.getLines是有意义的,如果你想映射一个复杂的lambda来处理不可变的行 –

1

看着你的连接速度有多慢(在2到6分钟之间才能得到gizmodo),你可能会发现Scala和Java之间的阅读速度不是问题,而是一个不可靠的互联网连接。如果您真的想测试速度差异,请尝试从本地服务器提供文件,以便从等式中删除互联网连接速度。

最后,对于高级HTTP客户端,我会看看Spray HTTP Client。喷雾是一个非常好的非阻塞(使用Actors)HTTP工具集。

+0

或者,如果您想要一个直接阻止的HTTP客户端API,则有http://www.bigbeeconsultants.co.uk/bee-client,默认情况下它将被阻止,但对非阻止请求使用futures。 (这是我自己的API)。 –