Scala编译器如何处理未使用的变量值?

Car*_*ten 6 memory performance scala apache-spark

使用Scala和Spark,我有以下结构:

val rdd1: RDD[String] = ...
val rdd2: RDD[(String, Any)] = ...

val rdd1pairs = rdd1.map(s => (s, s))
val result = rdd2.join(rdd1pairs)
              .map { case (_: String, (e: Any, _)) => e }
Run Code Online (Sandbox Code Playgroud)

映射rdd1到a 的目的PairRDDrdd2在后续步骤中加入.但是,我实际上只对值的感兴趣rdd2,因此最后一行中的映射步骤省略了键.其实,这是之间的交点rdd2,并rdd1与星火的执行join()效率的原因.

我的问题涉及以下关键字rdd1pairs:它们仅在语法原因上创建(允许连接)在第一个映射步骤中,之后被丢弃而没有任何用法.编译器如何处理这个?在内存消耗方面是否重要,我是否使用String s(如示例所示)?我应该更换它null还是0为了节省一点内存?编译器是否实际创建并存储了这些对象(引用),还是注意到它们从未被使用过?

mat*_*its 3

在这种情况下,我认为影响结果的是 Spark 驱动程序将执行的操作,而不是编译器。Spark 是否可以优化其执行管道以避免创建s. 我不确定,但我认为 Spark 会rdd1pairs在内存中创建 , 。

\n\n

(String, String)您可以使用以下命令来代替映射(String, Unit)

\n\n
rdd1.map(s => (s,()))\n
Run Code Online (Sandbox Code Playgroud)\n\n

您所做的基本上是rdd2基于 的过滤器rdd1。如果 rdd1 明显小于 rdd2,另一种方法是将 的数据表示为rdd1广播变量而不是 RDD,并简单地过滤rdd2。这避免了任何洗牌或减少阶段,因此可能会更快,但只有当数据rdd1足够小以适合每个节点时才有效。

\n\n

编辑:

\n\n

考虑使用 Unit 而不是 String 如何节省空间,请考虑以下示例:

\n\n
object size extends App {\n\n  (1 to 1000000).map(i => ("foo"+i, ()))\n  val input = readLine("prompt> ")\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
object size extends App {\n\n  (1 to 1000000).map(i => ("foo"+i, "foo"+i))\n  val input = readLine("prompt> ")\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用jstat本问题中描述的命令如何从命令行检查正在运行的 JVM 的堆使用情况?第一个版本使用的堆明显少于后者。

\n\n

编辑2:

\n\n

Unit实际上是一个没有内容的单例对象,因此从逻辑上讲,它不应该需要任何序列化。类型定义包含的事实Unit告诉您能够反序列化具有 Unit 类型字段的结构所需的一切。

\n\n

Spark 默认使用 Java 序列化。考虑以下:

\n\n
object Main extends App {\n\n  import java.io.{ObjectOutputStream, FileOutputStream}\n\n  case class Foo (a: String, b:String)\n  case class Bar (a: String, b:String, c: Unit)\n\n  val str = "abcdef"\n  val foo = Foo("abcdef", "xyz")\n  val bar = Bar("abcdef", "xyz", ())\n\n  val fos = new FileOutputStream( "foo.obj" )\n  val fo = new ObjectOutputStream( fos )\n  val bos = new FileOutputStream( "bar.obj" )\n  val bo = new ObjectOutputStream( bos )\n  fo writeObject foo\n  bo writeObject bar\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这两个文件的大小相同:

\n\n
\xef\xbf\xbd\xef\xbf\xbd sr Main$Foo3\xef\xbf\xbd,\xef\xbf\xbdz \\ L at Ljava/lang/String;L bq ~ xpt abcdeft xyz\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
\xef\xbf\xbd\xef\xbf\xbd sr Main$Bar+a!N\xef\xbf\xbd\xef\xbf\xbdb L at Ljava/lang/String;L bq ~ xpt abcdeft xyz\n
Run Code Online (Sandbox Code Playgroud)\n