Scala for Android的性能

T. *_*Rex 16 java performance android scala

我刚刚开始学习Scala,我正在度过我的生活.今天我也刚刚听说过Scala for Android,我完全迷上了.

但是,考虑到Scala有点像Java的超集,因为它是Java ++(我的意思是包含更多东西的Java)我想知道Scala代码在Android中是如何工作的?

此外,如果使用Scala编写,是否会影响Android应用程序的性能?也就是说,如果需要额外的工作来解释Scala代码.

om-*_*nom 41

为了解释一下@Aneesh的答案 - 是的,没有额外的工作来解释Scala字节码,因为它与Java字节码完全相同.

在此输入图像描述

请注意,在Android中运行代码时,还会有一个Java bytecode => Dalvik字节码步骤.

但是使用相同的砖块可以建造一个自行车,另一个人可以建造一个市政厅.例如,由于语言鼓励不变性,Scala会生成许多短生命对象.对于像HotSpot这样的成熟JVM,它在大约十年内并不是什么大问题.但对于Dalvik 来说,这是一个问题(在最近版本之前,对象池和已经创建的对象的严格重用是最常见的性能提示之一,即使对于Java也是如此).

接下来,写val与写作不同final Foo bar = ....在内部,此代码表示为字段+ getter(除非您使用val作为前缀private [this],将其转换为通常的final字段).var被翻译成field + getter + setter.它为什么如此重要?

旧版本的Android(2.2之前的版本)根本没有JIT,因此与直接现场访问相比,这大约是3x-7x的惩罚.最后,虽然谷歌指示你避免使用内部类而不喜欢软件包,但即使你不这样做,Scala也会创建很多内部类.考虑以下代码:

object Foo extends App {
    List(1,2,3,4)
      .map(x => x * 2)
      .filter(x => x % 3 == 0)
      .foreach(print)
}
Run Code Online (Sandbox Code Playgroud)

将创建多少个内部类?你可以说没有,但如果你运行scalac,你会看到:

Foo$$anonfun$1.class       // Map
Foo$$anonfun$2.class       // Filter
Foo$$anonfun$3.class       // Foreach
Foo$.class                 // Companion object class, because you've used `object`
Foo$delayedInit$body.class // Delayed init functionality that is used by App trait
Foo.class                  // Actual class
Run Code Online (Sandbox Code Playgroud)

因此会有一些惩罚,特别是如果你编写具有大量不变性和语法糖的惯用Scala代码.问题在于它高度依赖于您的部署(您是否针对较新的设备?)和实际的代码模式(您总是可以回到Java或至少在性能关键点中编写较少的惯用代码),并且那里提到的一些问题将会在下一版本中由语言本身(最后一个)解决.

原始图片来源是维基百科.

另请参阅Stack Overflow问题在Android上使用Scala值得吗?有很多开销吗?问题?对于您在开发过程中可能遇到的问题.


Enr*_*man 5

我发现这篇论文展示了两种语言之间的一些基准:

http://cse.aalto.fi/en/midcom-serveattachmentguid-1e3619151995344619111e3935b577b50548b758b75/denti_ngmast.pdf

我没有阅读整篇文章,但最后他们似乎会指出Java:

总之,我们认为Scala将来不会在移动应用程序开发中发挥重要作用,因为在设备上保持低能耗的重要性.Scala语言的优势在于其组件的扩展方式,这在移动设备中并不重要,因为应用程序往往根本不能扩展并保持小规模.

来自阿尔托大学的Mattia Denti和Jukka K. Nurminen的学分.


Dor*_*oby 5

虽然Scala"会正常工作",因为它像Java一样被编译为字节代码,但是需要考虑性能问题.惯用Scala代码往往会创建更多临时对象,而Dalvik VM对这些对象并不太友好.

在Android上使用Scala时,您应该注意以下事项:

  • 矢量,因为它们可能是浪费的(即使你只持有一个项目,总是占用32个项目的数组)
  • 对集合进行链接的方法 - 您应尽可能使用.view,以避免创建冗余集合.
  • 拳击 - Scala将在各种情况下打包你的原语,比如使用Generics,使用Option [Int]和一些匿名函数.
  • for循环可能会浪费内存,请考虑在敏感部分使用while循环替换它们
  • 隐式转换 - 调用str.indexWhere(...)会在字符串上分配包装器对象.可能很浪费.
  • 每次访问密钥时,Scala的Map都会分配一个Option [V].我有时必须用Java的HashMap替换它.

当然,您应该只在使用分析器后优化瓶颈的位置.

您可以在此博客文章中阅读有关上述建议的更多信息:http: //blogs.microsoft.co.il/dorony/2014/10/07/scala-performance-tips-on-android/