Java 具有特殊类型的Scala优化:长和

Java 具有特殊类型的Scala优化:长和,java,scala,performance,java-stream,bytecode,Java,Scala,Performance,Java Stream,Bytecode,我有以下简单的代码 val longs: Vector[Long] = (1L to 1000000L).toVector 还有所谓的等价Java def jLongs: java.util.stream.LongStream = java.util.stream.LongStream .iterate(1L, (i: Long) => i <= 1000000L, (i: Long) => i + 1L) 所以在我看来,scala版本被迫加载一百万个对象 这就是它

我有以下简单的代码

val longs: Vector[Long] = (1L to 1000000L).toVector
还有所谓的等价Java

def jLongs: java.util.stream.LongStream = java.util.stream.LongStream
    .iterate(1L, (i: Long) => i <= 1000000L, (i: Long) => i + 1L)
所以在我看来,scala版本被迫加载一百万个对象

这就是它这么慢的原因吗?我怎么能告诉你要专攻长跑


此外,有趣且违反直觉的是,java代码返回一个对象,而在scala中返回一个原语long(参见
ARETURN
vs.
LRETURN
)。

查看字节码是徒劳的。区别在于
流是什么。
LongStream
根据需要生成元素。它不是一个数据结构;它是一个控制结构——一个对其他数据源的潜在循环。您的Java可以归结为

var总和:长=0

因为(i查看字节码是徒劳的。区别在于
流是什么。
长流
按需生成元素。它不是一个数据结构;它是一个控制结构——一个对其他数据源的潜在循环。Java可以归结为

var总和:长=0

对于(我)来说,有没有什么方法可以专门用于long?有没有什么方法可以专门用于long?
@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
class BoxingScala {
  val longs: Vector[Long] = (1L to 1000000L).toVector
  def jLongs: java.util.stream.LongStream = java.util.stream.LongStream
    .iterate(1L, (i: Long) => i <= 1000000L, (i: Long) => i + 1L)

  @Benchmark def a: Long = longs.sum

  @Benchmark def b: java.lang.Long = jLongs.sum()
}
  // access flags 0x1
  public a()J
  @Lorg/openjdk/jmh/annotations/Benchmark;()
   L0
    LINENUMBER <benchmark a> L0
    ALOAD 0
    INVOKEVIRTUAL gurghet/BoxingScala.longs ()Lscala/collection/immutable/Vector;
    GETSTATIC scala/math/Numeric$LongIsIntegral$.MODULE$ : Lscala/math/Numeric$LongIsIntegral$;
    INVOKEVIRTUAL scala/collection/immutable/Vector.sum (Lscala/math/Numeric;)Ljava/lang/Object;
    INVOKESTATIC scala/runtime/BoxesRunTime.unboxToLong (Ljava/lang/Object;)J
    LRETURN
   L1
    LOCALVARIABLE this Lgurghet/BoxingScala; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1

  // access flags 0x1
  public b()Ljava/lang/Long;
  @Lorg/openjdk/jmh/annotations/Benchmark;()
   L0
    LINENUMBER <benchmark b> L0
    GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
    ALOAD 0
    INVOKEVIRTUAL gurghet/BoxingScala.jLongs ()Ljava/util/stream/LongStream;
    INVOKEINTERFACE java/util/stream/LongStream.sum ()J (itf)
    INVOKEVIRTUAL scala/Predef$.long2Long (J)Ljava/lang/Long;
    ARETURN
   L1
    LOCALVARIABLE this Lgurghet/BoxingScala; L0 L1 0
    MAXSTACK = 3
    MAXLOCALS = 1
 L1
    LINENUMBER <init> L1
    ALOAD 0
    NEW scala/runtime/RichLong
    DUP
    GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
    LCONST_1
    INVOKEVIRTUAL scala/Predef$.longWrapper (J)J
    INVOKESPECIAL scala/runtime/RichLong.<init> (J)V
    LDC 1000000
    INVOKESTATIC scala/runtime/BoxesRunTime.boxToLong (J)Ljava/lang/Long;
    INVOKEVIRTUAL scala/runtime/RichLong.to (Ljava/lang/Object;)Lscala/collection/immutable/NumericRange$Inclusive;
    INVOKEVIRTUAL scala/collection/immutable/NumericRange$Inclusive.toVector ()Lscala/collection/immutable/Vector;
    PUTFIELD gurghet/BoxingScala.longs : Lscala/collection/immutable/Vector;