16

我刚开始学习Scala,我正在享受我的生活。今天我也刚刚听说了适用于 Android 的 Scala,我完全被迷住了。

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

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

4

4 回答 4

41

稍微解释一下@Aneesh 的答案——是的,解释 Scala 字节码不需要额外的工作,因为它与 Java 字节码完全相同

在此处输入图像描述

请注意,当您在 Android 中运行代码时,还有一个 Java 字节码 => 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 的惩罚。最后,虽然 Google 指示您避免使用内部类而更喜欢包,但 Scala 会创建很多内部类,即使您不这么写也是如此。考虑这段代码:

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

将创建多少个内部类?你可以说没有,但如果你运行 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

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

原始图片来源是维基百科

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

于 2013-09-30T12:59:57.330 回答
5

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

以下是在 Android 上使用 Scala 时应注意的一些事项:

  • 向量,因为它们可能是浪费的(总是占用 32 个项目的数组,即使你只拿着一个项目)
  • 集合上的方法链接 - 您应该尽可能使用 .view ,以避免创建冗余集合。
  • 装箱 - Scala 将在各种情况下装箱您的原语,例如使用泛型、使用 Option[Int] 以及在一些匿名函数中。
  • for 循环会浪费内存,请考虑在敏感部分用 while 循环替换它们
  • 隐式转换 - 调用 likestr.indexWhere(...)将在字符串上分配一个包装对象。可能很浪费。
  • 每次访问键时,Scala 的 Map 都会分配一个 Option[V] 。有时我不得不用 Java 的 HashMap 替换它。

当然,您应该只在使用分析器后优化成为瓶颈的地方。

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

于 2014-10-07T21:14:46.317 回答
5

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

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

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

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

感谢阿尔托大学的 Mattia Denti 和 Jukka K. Nurminen。

于 2013-09-30T13:39:00.863 回答
2

Scala 编译器将创建 JVM 字节码。所以基本上在较低级别,它就像运行 Java。所以性能将与Java相当。

但是,Scala 编译器如何创建字节码可能会对性能产生一些影响。我想说,由于 Scala 是新的,并且由于其字节码生成可能效率低下,Scala 会比 Android 上的 Java 慢一点,尽管不会慢很多。

于 2013-09-30T11:46:56.240 回答