Ph-苯
太水了,所以发到茶馆了。

众所周知,Java的对象都是分配在堆上的,这会导致大量的指针操作,非常耗时。而像C#的值类型那样,直接把对象里的各个字段展平成结构体,就能省下这些开销,大幅提升效率。但是怎样在现版本Java做出值类型的效果呢?Java只有8种值类型,即8种基本数据类型

懒得写那么多了,直接上结果吧。

如果内联类包装的是基本数据类型(MyValueVec2i和MyValueVec2f),那么会有较明显的性能提升;如果包装的是数组(MyValueVec3i),那么与把元素平展的对象(MyClassVec3i)相比,性能并无多大差别。
  1. @JvmInline
  2. value class MyValueVec2i private constructor(private val bits: Long) {
  3.     constructor(x: Int, y: Int) : this((x.toLong() shl 32) and y.toLong())
  4.    
  5.     val x: Int get() = (bits ushr 32).toInt()
  6.     val y: Int get() = bits.toInt()
  7.     operator fun plus(v: MyValueVec2i): MyValueVec2i = MyValueVec2i(x + v.x, y + v.y)
  8.     operator fun minus(v: MyValueVec2i): MyValueVec2i = MyValueVec2i(x - v.x, y - v.y)
  9. }
复制代码
  1. class MyClassVec2i(val x: Int, val y: Int) {
  2.     operator fun plus(v: MyClassVec2i): MyClassVec2i = MyClassVec2i(x + v.x, y + v.y)
  3.     operator fun minus(v: MyClassVec2i): MyClassVec2i = MyClassVec2i(x - v.x, y - v.y)
  4. }
复制代码
  1. @JvmInline
  2. value class MyValueVec2f private constructor(private val bits: Long) {
  3.     constructor(x: Float, y: Float) : this((x.toBits().toLong() shl 32) and y.toBits().toLong())
  4.    
  5.     val x: Float get() = Float.fromBits((bits ushr 32).toInt())
  6.     val y: Float get() = Float.fromBits(bits.toInt())
  7.     operator fun plus(v: MyValueVec2f): MyValueVec2f = MyValueVec2f(x + v.x, y + v.y)
  8.     operator fun minus(v: MyValueVec2f): MyValueVec2f = MyValueVec2f(x - v.x, y - v.y)
  9. }
复制代码
  1. class MyClassVec2f(val x: Float, val y: Float) {
  2.     operator fun plus(v: MyClassVec2f): MyClassVec2f = MyClassVec2f(x + v.x, y + v.y)
  3.     operator fun minus(v: MyClassVec2f): MyClassVec2f = MyClassVec2f(x - v.x, y - v.y)
  4. }
复制代码
  1. @JvmInline
  2. value class MyValueVec3i private constructor(val values: IntArray) {
  3.     constructor(x: Int, y: Int, z: Int) : this(intArrayOf(x, y, z))
  4.    
  5.     val x: Int get() = values[0]
  6.     val y: Int get() = values[1]
  7.     val z: Int get() = values[2]
  8.     operator fun plus(v: MyValueVec3i): MyValueVec3i = MyValueVec3i(x + v.x, y + v.y, z + v.z)
  9.     operator fun minus(v: MyValueVec3i): MyValueVec3i = MyValueVec3i(x - v.x, y - v.y, z + v.z)
  10. }
复制代码
  1. class MyClassVec3i(val x: Int, val y: Int, val z: Int) {
  2.     operator fun plus(v: MyClassVec3i): MyClassVec3i = MyClassVec3i(x + v.x, y + v.y, z + v.z)
  3.     operator fun minus(v: MyClassVec3i): MyClassVec3i = MyClassVec3i(x - v.x, y - v.y, z + v.z)
  4. }
复制代码
  1. fun main(args: Array<String>) {
  2.     thread { test(::testValue2i, ::testClass2i, "2i") }
  3.     thread { test(::testValue2f, ::testClass2f, "2f") }
  4.     thread { test(::testValue3i, ::testClass3i, "3i") }
  5. }

  6. private inline fun test(testValue: () -> Unit, testClass: () -> Unit, suffix: String) {
  7.     val c = 10
  8.     val valueTimes = IntArray(c)
  9.     val classTimes = IntArray(c)
  10.     for (i in 0 until c) {
  11.         val t0 = System.currentTimeMillis()
  12.         testValue()
  13.         val t1 = System.currentTimeMillis()
  14.         testClass()
  15.         val t2 = System.currentTimeMillis()
  16.         valueTimes[i] = (t1 - t0).toInt()
  17.         classTimes[i] = (t2 - t1).toInt()
  18.     }
  19.     println("value$suffix: ${valueTimes.average()}\nclass$suffix: ${classTimes.average()}")
  20. }

  21. private fun testValue3i() {
  22.     var v = MyValueVec3i(1, 2, 3)
  23.     for (i in 1..10_0000_0000) {
  24.         v = v + v - v
  25.     }
  26. }

  27. private fun testClass3i() {
  28.     var v = MyClassVec3i(1, 2, 3)
  29.     for (i in 1..10_0000_0000) {
  30.         v = v + v - v
  31.     }
  32. }

  33. private fun testValue2i() {
  34.     var v = MyValueVec2i(1, 2)
  35.     for (i in 1..10_0000_0000) {
  36.         v = v + v - v
  37.     }
  38. }

  39. private fun testClass2i() {
  40.     var v = MyClassVec2i(1, 2)
  41.     for (i in 1..10_0000_0000) {
  42.         v = v + v - v
  43.     }
  44. }

  45. private fun testValue2f() {
  46.     var v = MyValueVec2f(1f, 2f)
  47.     for (i in 1..10_0000_0000) {
  48.         v = v + v - v
  49.     }
  50. }

  51. private fun testClass2f() {
  52.     var v = MyClassVec2f(1f, 2f)
  53.     for (i in 1..10_0000_0000) {
  54.         v = v + v - v
  55.     }
  56. }
复制代码
控制台输出:
value2i: 570.4
class2i: 4458.9
value2f: 1332.9
class2f: 4189.7
value3i: 4034.1
class3i: 3821.7


hans0000
这个我到不清楚,前段时间看到,nodejs比python效率高几十倍,还了解了现在c#的效率要比java高的,不过其实一般也没啥的,看具体**了

我跑计算PI,规模是1_000_000_000,python短时间跑不出来,nodejs-600ms,java-800ms吧,不清楚是否有纰漏

Ph-苯
hans0000 发表于 2022-11-29 17:54
这个我到不清楚,前段时间看到,nodejs比python效率高几十倍,还了解了现在c#的效率要比java高的,不过其实 ...

python的float是完完全全的对象,而且比java的Float还要慢得多,唉。

看见没了
666啊,一般人真看不懂

幻灭神使RL
《太水了》
我似乎就没发过如此正常的帖(

Doomsday_Envoy
B乎上也看过一些代码优化的技术和段子,所以毛子的五层指针优化是完完全全的段子还是说不定真的可行的技术

Ph-苯
Doomsday_Envoy 发表于 2022-11-29 21:37
B乎上也看过一些代码优化的技术和段子,所以毛子的五层指针优化是完完全全的段子还是说不定真的可行的技术[ ...

什么段子?有没有链接?😍
五层指针优化又是什么?

下一页 最后一页