RFR: 8299193: Micro-optimization in Buffer
Per Minborg
pminborg at openjdk.org
Thu Dec 22 13:52:48 UTC 2022
On Wed, 21 Dec 2022 12:22:33 GMT, Per Minborg <pminborg at openjdk.org> wrote:
> It is possible to declare the field `capacity` in `java.nio.Buffer` `final`, potentially unlocking performance optimizations.
Benchmarking with and without `final` didn't affect performance noticeable when run under the current JVM implementation.
Final | | | | | |
-- | -- | -- | -- | -- | -- | --
Benchmark | (size) | Mode | Cnt | Score | Error | Units
ByteBuffers.testDirectLoopGetByte | 16 | avgt | 30 | 4.517 | 0.027 | ns/op
ByteBuffers.testDirectLoopGetByteRO | 16 | avgt | 30 | 4.461 | 0.019 | ns/op
ByteBuffers.testDirectLoopGetByteSwap | 16 | avgt | 30 | 4.461 | 0.018 | ns/op
ByteBuffers.testDirectLoopGetByteSwapRO | 16 | avgt | 30 | 4.465 | 0.024 | ns/op
ByteBuffers.testDirectLoopGetChar | 16 | avgt | 30 | 4.455 | 0.012 | ns/op
ByteBuffers.testDirectLoopGetCharRO | 16 | avgt | 30 | 4.442 | 0.013 | ns/op
ByteBuffers.testDirectLoopGetCharSwap | 16 | avgt | 30 | 3.994 | 0.01 | ns/op
ByteBuffers.testDirectLoopGetCharSwapRO | 16 | avgt | 30 | 4.43 | 0.005 | ns/op
ByteBuffers.testDirectLoopGetDouble | 16 | avgt | 30 | 2.779 | 0.016 | ns/op
ByteBuffers.testDirectLoopGetDoubleRO | 16 | avgt | 30 | 2.756 | 0.008 | ns/op
ByteBuffers.testDirectLoopGetDoubleSwap | 16 | avgt | 30 | 2.762 | 0.015 | ns/op
ByteBuffers.testDirectLoopGetDoubleSwapRO | 16 | avgt | 30 | 2.783 | 0.019 | ns/op
ByteBuffers.testDirectLoopGetFloat | 16 | avgt | 30 | 3.237 | 0.019 | ns/op
ByteBuffers.testDirectLoopGetFloatRO | 16 | avgt | 30 | 3.224 | 0.01 | ns/op
ByteBuffers.testDirectLoopGetFloatSwap | 16 | avgt | 30 | 3.163 | 0.004 | ns/op
ByteBuffers.testDirectLoopGetFloatSwapRO | 16 | avgt | 30 | 3.24 | 0.028 | ns/op
ByteBuffers.testDirectLoopGetInt | 16 | avgt | 30 | 3.141 | 0.01 | ns/op
ByteBuffers.testDirectLoopGetIntRO | 16 | avgt | 30 | 3.128 | 0.007 | ns/op
ByteBuffers.testDirectLoopGetIntSwap | 16 | avgt | 30 | 3.166 | 0.018 | ns/op
ByteBuffers.testDirectLoopGetIntSwapRO | 16 | avgt | 30 | 3.214 | 0.122 | ns/op
ByteBuffers.testDirectLoopGetLong | 16 | avgt | 30 | 2.784 | 0.011 | ns/op
ByteBuffers.testDirectLoopGetLongRO | 16 | avgt | 30 | 2.778 | 0.013 | ns/op
ByteBuffers.testDirectLoopGetLongSwap | 16 | avgt | 30 | 2.788 | 0.007 | ns/op
ByteBuffers.testDirectLoopGetLongSwapRO | 16 | avgt | 30 | 2.771 | 0.005 | ns/op
ByteBuffers.testDirectLoopGetShort | 16 | avgt | 30 | 5.017 | 0.037 | ns/op
ByteBuffers.testDirectLoopGetShortRO | 16 | avgt | 30 | 4.982 | 0.006 | ns/op
ByteBuffers.testDirectLoopGetShortSwap | 16 | avgt | 30 | 4.01 | 0.031 | ns/op
ByteBuffers.testDirectLoopGetShortSwapRO | 16 | avgt | 30 | 5.017 | 0.052 | ns/op
ByteBuffers.testDirectLoopPutByte | 16 | avgt | 30 | 4.381 | 0.017 | ns/op
ByteBuffers.testDirectLoopPutByteSwap | 16 | avgt | 30 | 4.404 | 0.029 | ns/op
ByteBuffers.testDirectLoopPutChar | 16 | avgt | 30 | 3.981 | 0.019 | ns/op
ByteBuffers.testDirectLoopPutCharSwap | 16 | avgt | 30 | 3.951 | 0.006 | ns/op
ByteBuffers.testDirectLoopPutDouble | 16 | avgt | 30 | 2.798 | 0.009 | ns/op
ByteBuffers.testDirectLoopPutDoubleSwap | 16 | avgt | 30 | 2.816 | 0.016 | ns/op
ByteBuffers.testDirectLoopPutFloat | 16 | avgt | 30 | 3.127 | 0.005 | ns/op
ByteBuffers.testDirectLoopPutFloatSwap | 16 | avgt | 30 | 3.185 | 0.075 | ns/op
ByteBuffers.testDirectLoopPutInt | 16 | avgt | 30 | 3.233 | 0.05 | ns/op
ByteBuffers.testDirectLoopPutIntSwap | 16 | avgt | 30 | 3.182 | 0.022 | ns/op
ByteBuffers.testDirectLoopPutLong | 16 | avgt | 30 | 2.768 | 0.029 | ns/op
ByteBuffers.testDirectLoopPutLongSwap | 16 | avgt | 30 | 2.746 | 0.003 | ns/op
ByteBuffers.testDirectLoopPutShort | 16 | avgt | 30 | 3.981 | 0.006 | ns/op
ByteBuffers.testDirectLoopPutShortSwap | 16 | avgt | 30 | 3.959 | 0.015 | ns/op
ByteBuffers.testHeapBulkGetByte | 16 | avgt | 30 | 2.547 | 0.02 | ns/op
ByteBuffers.testHeapBulkPutByte | 16 | avgt | 30 | 2.532 | 0.023 | ns/op
ByteBuffers.testHeapLoopGetByte | 16 | avgt | 30 | 5.974 | 0.07 | ns/op
ByteBuffers.testHeapLoopGetByteRO | 16 | avgt | 30 | 6.006 | 0.252 | ns/op
ByteBuffers.testHeapLoopGetByteSwap | 16 | avgt | 30 | 5.878 | 0.019 | ns/op
ByteBuffers.testHeapLoopGetByteSwapRO | 16 | avgt | 30 | 6.086 | 0.026 | ns/op
ByteBuffers.testHeapLoopGetChar | 16 | avgt | 30 | 4.847 | 0.051 | ns/op
ByteBuffers.testHeapLoopGetCharRO | 16 | avgt | 30 | 4.729 | 0.014 | ns/op
ByteBuffers.testHeapLoopGetCharSwap | 16 | avgt | 30 | 4.204 | 0.028 | ns/op
ByteBuffers.testHeapLoopGetCharSwapRO | 16 | avgt | 30 | 4.677 | 0.005 | ns/op
ByteBuffers.testHeapLoopGetDouble | 16 | avgt | 30 | 2.971 | 0.011 | ns/op
ByteBuffers.testHeapLoopGetDoubleRO | 16 | avgt | 30 | 2.968 | 0.012 | ns/op
ByteBuffers.testHeapLoopGetDoubleSwap | 16 | avgt | 30 | 2.915 | 0.005 | ns/op
ByteBuffers.testHeapLoopGetDoubleSwapRO | 16 | avgt | 30 | 2.968 | 0.013 | ns/op
ByteBuffers.testHeapLoopGetFloat | 16 | avgt | 30 | 3.32 | 0.003 | ns/op
ByteBuffers.testHeapLoopGetFloatRO | 16 | avgt | 30 | 3.32 | 0.005 | ns/op
ByteBuffers.testHeapLoopGetFloatSwap | 16 | avgt | 30 | 3.317 | 0.004 | ns/op
ByteBuffers.testHeapLoopGetFloatSwapRO | 16 | avgt | 30 | 3.32 | 0.003 | ns/op
ByteBuffers.testHeapLoopGetInt | 16 | avgt | 30 | 3.315 | 0.004 | ns/op
ByteBuffers.testHeapLoopGetIntRO | 16 | avgt | 30 | 3.316 | 0.003 | ns/op
ByteBuffers.testHeapLoopGetIntSwap | 16 | avgt | 30 | 3.317 | 0.004 | ns/op
ByteBuffers.testHeapLoopGetIntSwapRO | 16 | avgt | 30 | 3.319 | 0.008 | ns/op
ByteBuffers.testHeapLoopGetLong | 16 | avgt | 30 | 2.927 | 0.004 | ns/op
ByteBuffers.testHeapLoopGetLongRO | 16 | avgt | 30 | 2.928 | 0.005 | ns/op
ByteBuffers.testHeapLoopGetLongSwap | 16 | avgt | 30 | 2.911 | 0.003 | ns/op
ByteBuffers.testHeapLoopGetLongSwapRO | 16 | avgt | 30 | 2.977 | 0.009 | ns/op
ByteBuffers.testHeapLoopGetShort | 16 | avgt | 30 | 5.296 | 0.014 | ns/op
ByteBuffers.testHeapLoopGetShortRO | 16 | avgt | 30 | 5.301 | 0.01 | ns/op
ByteBuffers.testHeapLoopGetShortSwap | 16 | avgt | 30 | 4.295 | 0.015 | ns/op
ByteBuffers.testHeapLoopGetShortSwapRO | 16 | avgt | 30 | 5.305 | 0.019 | ns/op
ByteBuffers.testHeapLoopPutByte | 16 | avgt | 30 | 4.517 | 0.027 | ns/op
ByteBuffers.testHeapLoopPutByteSwap | 16 | avgt | 30 | 4.516 | 0.023 | ns/op
ByteBuffers.testHeapLoopPutChar | 16 | avgt | 30 | 4.24 | 0.01 | ns/op
ByteBuffers.testHeapLoopPutCharSwap | 16 | avgt | 30 | 4.229 | 0.008 | ns/op
ByteBuffers.testHeapLoopPutDouble | 16 | avgt | 30 | 3.049 | 0.012 | ns/op
ByteBuffers.testHeapLoopPutDoubleSwap | 16 | avgt | 30 | 2.989 | 0.009 | ns/op
ByteBuffers.testHeapLoopPutFloat | 16 | avgt | 30 | 3.498 | 0.008 | ns/op
ByteBuffers.testHeapLoopPutFloatSwap | 16 | avgt | 30 | 3.378 | 0.009 | ns/op
ByteBuffers.testHeapLoopPutInt | 16 | avgt | 30 | 3.422 | 0.009 | ns/op
ByteBuffers.testHeapLoopPutIntSwap | 16 | avgt | 30 | 3.405 | 0.007 | ns/op
ByteBuffers.testHeapLoopPutLong | 16 | avgt | 30 | 3.025 | 0.006 | ns/op
ByteBuffers.testHeapLoopPutLongSwap | 16 | avgt | 30 | 3.184 | 0.009 | ns/op
ByteBuffers.testHeapLoopPutShort | 16 | avgt | 30 | 4.218 | 0.007 | ns/op
ByteBuffers.testHeapLoopPutShortSwap | 16 | avgt | 30 | 4.215 | 0.007 | ns/op
ByteBuffers.testDirectLoopGetByte | 1024 | avgt | 30 | 597.756 | 1.464 | ns/op
ByteBuffers.testDirectLoopGetByteRO | 1024 | avgt | 30 | 599.101 | 1.923 | ns/op
Baseline | | | | | | | |
-- | -- | -- | -- | -- | -- | -- | -- | --
Improvement | | Benchmark | (size) | Mode | Cnt | Score | Error | Units
0.016 | | ByteBuffers.testDirectLoopGetByte | 16 | avgt | 30 | 4.533 | 0.031 | ns/op
0.037 | | ByteBuffers.testDirectLoopGetByteRO | 16 | avgt | 30 | 4.498 | 0.016 | ns/op
0.042 | | ByteBuffers.testDirectLoopGetByteSwap | 16 | avgt | 30 | 4.503 | 0.032 | ns/op
0.003 | | ByteBuffers.testDirectLoopGetByteSwapRO | 16 | avgt | 30 | 4.468 | 0.013 | ns/op
0.019 | | ByteBuffers.testDirectLoopGetChar | 16 | avgt | 30 | 4.474 | 0.045 | ns/op
0.014 | | ByteBuffers.testDirectLoopGetCharRO | 16 | avgt | 30 | 4.456 | 0.021 | ns/op
0.043 | | ByteBuffers.testDirectLoopGetCharSwap | 16 | avgt | 30 | 4.037 | 0.045 | ns/op
0.057 | | ByteBuffers.testDirectLoopGetCharSwapRO | 16 | avgt | 30 | 4.487 | 0.019 | ns/op
0.002 | | ByteBuffers.testDirectLoopGetDouble | 16 | avgt | 30 | 2.781 | 0.019 | ns/op
0.016 | | ByteBuffers.testDirectLoopGetDoubleRO | 16 | avgt | 30 | 2.772 | 0.018 | ns/op
0.014 | | ByteBuffers.testDirectLoopGetDoubleSwap | 16 | avgt | 30 | 2.776 | 0.015 | ns/op
-0.028 | | ByteBuffers.testDirectLoopGetDoubleSwapRO | 16 | avgt | 30 | 2.755 | 0.005 | ns/op
-0.036 | | ByteBuffers.testDirectLoopGetFloat | 16 | avgt | 30 | 3.201 | 0.017 | ns/op
0.037 | | ByteBuffers.testDirectLoopGetFloatRO | 16 | avgt | 30 | 3.261 | 0.048 | ns/op
0.063 | | ByteBuffers.testDirectLoopGetFloatSwap | 16 | avgt | 30 | 3.226 | 0.07 | ns/op
0.005 | | ByteBuffers.testDirectLoopGetFloatSwapRO | 16 | avgt | 30 | 3.245 | 0.037 | ns/op
-0.001 | | ByteBuffers.testDirectLoopGetInt | 16 | avgt | 30 | 3.14 | 0.008 | ns/op
0.044 | | ByteBuffers.testDirectLoopGetIntRO | 16 | avgt | 30 | 3.172 | 0.024 | ns/op
-0.008 | | ByteBuffers.testDirectLoopGetIntSwap | 16 | avgt | 30 | 3.158 | 0.012 | ns/op
-0.076 | | ByteBuffers.testDirectLoopGetIntSwapRO | 16 | avgt | 30 | 3.138 | 0.007 | ns/op
0.028 | | ByteBuffers.testDirectLoopGetLong | 16 | avgt | 30 | 2.812 | 0.034 | ns/op
0.022 | | ByteBuffers.testDirectLoopGetLongRO | 16 | avgt | 30 | 2.8 | 0.04 | ns/op
0.022 | | ByteBuffers.testDirectLoopGetLongSwap | 16 | avgt | 30 | 2.81 | 0.044 | ns/op
0.012 | | ByteBuffers.testDirectLoopGetLongSwapRO | 16 | avgt | 30 | 2.783 | 0.027 | ns/op
0.053 | | ByteBuffers.testDirectLoopGetShort | 16 | avgt | 30 | 5.07 | 0.1 | ns/op
0.094 | | ByteBuffers.testDirectLoopGetShortRO | 16 | avgt | 30 | 5.076 | 0.065 | ns/op
0.051 | | ByteBuffers.testDirectLoopGetShortSwap | 16 | avgt | 30 | 4.061 | 0.041 | ns/op
0.115 | | ByteBuffers.testDirectLoopGetShortSwapRO | 16 | avgt | 30 | 5.132 | 0.198 | ns/op
-0.016 | | ByteBuffers.testDirectLoopPutByte | 16 | avgt | 30 | 4.365 | 0.006 | ns/op
-0.013 | | ByteBuffers.testDirectLoopPutByteSwap | 16 | avgt | 30 | 4.391 | 0.068 | ns/op
0.041 | | ByteBuffers.testDirectLoopPutChar | 16 | avgt | 30 | 4.022 | 0.112 | ns/op
0.111 | | ByteBuffers.testDirectLoopPutCharSwap | 16 | avgt | 30 | 4.062 | 0.236 | ns/op
0.001 | | ByteBuffers.testDirectLoopPutDouble | 16 | avgt | 30 | 2.799 | 0.017 | ns/op
0.19 | | ByteBuffers.testDirectLoopPutDoubleSwap | 16 | avgt | 30 | 3.006 | 0.308 | ns/op
0.146 | | ByteBuffers.testDirectLoopPutFloat | 16 | avgt | 30 | 3.273 | 0.008 | ns/op
-0.054 | | ByteBuffers.testDirectLoopPutFloatSwap | 16 | avgt | 30 | 3.131 | 0.013 | ns/op
-0.064 | | ByteBuffers.testDirectLoopPutInt | 16 | avgt | 30 | 3.169 | 0.004 | ns/op
-0.045 | | ByteBuffers.testDirectLoopPutIntSwap | 16 | avgt | 30 | 3.137 | 0.004 | ns/op
-0.026 | | ByteBuffers.testDirectLoopPutLong | 16 | avgt | 30 | 2.742 | 0.003 | ns/op
-0.007 | | ByteBuffers.testDirectLoopPutLongSwap | 16 | avgt | 30 | 2.739 | 0.003 | ns/op
-0.012 | | ByteBuffers.testDirectLoopPutShort | 16 | avgt | 30 | 3.969 | 0.004 | ns/op
-0.019 | | ByteBuffers.testDirectLoopPutShortSwap | 16 | avgt | 30 | 3.94 | 0.007 | ns/op
-0.048 | | ByteBuffers.testHeapBulkGetByte | 16 | avgt | 30 | 2.499 | 0.015 | ns/op
-0.044 | | ByteBuffers.testHeapBulkPutByte | 16 | avgt | 30 | 2.488 | 0.003 | ns/op
-0.039 | | ByteBuffers.testHeapLoopGetByte | 16 | avgt | 30 | 5.935 | 0.172 | ns/op
-0.039 | | ByteBuffers.testHeapLoopGetByteRO | 16 | avgt | 30 | 5.967 | 0.215 | ns/op
0.017 | | ByteBuffers.testHeapLoopGetByteSwap | 16 | avgt | 30 | 5.895 | 0.027 | ns/op
-0.043 | | ByteBuffers.testHeapLoopGetByteSwapRO | 16 | avgt | 30 | 6.043 | 0.136 | ns/op
-0.127 | | ByteBuffers.testHeapLoopGetChar | 16 | avgt | 30 | 4.72 | 0.04 | ns/op
0.008 | | ByteBuffers.testHeapLoopGetCharRO | 16 | avgt | 30 | 4.737 | 0.032 | ns/op
0.001 | | ByteBuffers.testHeapLoopGetCharSwap | 16 | avgt | 30 | 4.205 | 0.02 | ns/op
0.082 | | ByteBuffers.testHeapLoopGetCharSwapRO | 16 | avgt | 30 | 4.759 | 0.036 | ns/op
0.01 | | ByteBuffers.testHeapLoopGetDouble | 16 | avgt | 30 | 2.981 | 0.012 | ns/op
0.015 | | ByteBuffers.testHeapLoopGetDoubleRO | 16 | avgt | 30 | 2.983 | 0.014 | ns/op
0.007 | | ByteBuffers.testHeapLoopGetDoubleSwap | 16 | avgt | 30 | 2.922 | 0.006 | ns/op
0.031 | | ByteBuffers.testHeapLoopGetDoubleSwapRO | 16 | avgt | 30 | 2.999 | 0.016 | ns/op
0.024 | | ByteBuffers.testHeapLoopGetFloat | 16 | avgt | 30 | 3.344 | 0.011 | ns/op
0.092 | | ByteBuffers.testHeapLoopGetFloatRO | 16 | avgt | 30 | 3.412 | 0.103 | ns/op
0.038 | | ByteBuffers.testHeapLoopGetFloatSwap | 16 | avgt | 30 | 3.355 | 0.024 | ns/op
0.018 | | ByteBuffers.testHeapLoopGetFloatSwapRO | 16 | avgt | 30 | 3.338 | 0.01 | ns/op
0.014 | | ByteBuffers.testHeapLoopGetInt | 16 | avgt | 30 | 3.329 | 0.007 | ns/op
0.013 | | ByteBuffers.testHeapLoopGetIntRO | 16 | avgt | 30 | 3.329 | 0.005 | ns/op
0.015 | | ByteBuffers.testHeapLoopGetIntSwap | 16 | avgt | 30 | 3.332 | 0.011 | ns/op
0.054 | | ByteBuffers.testHeapLoopGetIntSwapRO | 16 | avgt | 30 | 3.373 | 0.078 | ns/op
0.014 | | ByteBuffers.testHeapLoopGetLong | 16 | avgt | 30 | 2.941 | 0.01 | ns/op
0.057 | | ByteBuffers.testHeapLoopGetLongRO | 16 | avgt | 30 | 2.985 | 0.025 | ns/op
0.077 | | ByteBuffers.testHeapLoopGetLongSwap | 16 | avgt | 30 | 2.988 | 0.075 | ns/op
-0.021 | | ByteBuffers.testHeapLoopGetLongSwapRO | 16 | avgt | 30 | 2.956 | 0.018 | ns/op
-0.043 | | ByteBuffers.testHeapLoopGetShort | 16 | avgt | 30 | 5.253 | 0.043 | ns/op
-0.085 | | ByteBuffers.testHeapLoopGetShortRO | 16 | avgt | 30 | 5.216 | 0.007 | ns/op
0.025 | | ByteBuffers.testHeapLoopGetShortSwap | 16 | avgt | 30 | 4.32 | 0.099 | ns/op
0.142 | | ByteBuffers.testHeapLoopGetShortSwapRO | 16 | avgt | 30 | 5.447 | 0.279 | ns/op
0.127 | | ByteBuffers.testHeapLoopPutByte | 16 | avgt | 30 | 4.644 | 0.116 | ns/op
0.199 | | ByteBuffers.testHeapLoopPutByteSwap | 16 | avgt | 30 | 4.715 | 0.148 | ns/op
0.221 | | ByteBuffers.testHeapLoopPutChar | 16 | avgt | 30 | 4.461 | 0.343 | ns/op
-0.069 | | ByteBuffers.testHeapLoopPutCharSwap | 16 | avgt | 30 | 4.16 | 0.008 | ns/op
-0.044 | | ByteBuffers.testHeapLoopPutDouble | 16 | avgt | 30 | 3.005 | 0.021 | ns/op
-0.053 | | ByteBuffers.testHeapLoopPutDoubleSwap | 16 | avgt | 30 | 2.936 | 0.002 | ns/op
-0.048 | | ByteBuffers.testHeapLoopPutFloat | 16 | avgt | 30 | 3.45 | 0.02 | ns/op
-0.061 | | ByteBuffers.testHeapLoopPutFloatSwap | 16 | avgt | 30 | 3.317 | 0.003 | ns/op
-0.054 | | ByteBuffers.testHeapLoopPutInt | 16 | avgt | 30 | 3.368 | 0.008 | ns/op
-0.039 | | ByteBuffers.testHeapLoopPutIntSwap | 16 | avgt | 30 | 3.366 | 0.056 | ns/op
-0.03 | | ByteBuffers.testHeapLoopPutLong | 16 | avgt | 30 | 2.995 | 0.019 | ns/op
-0.051 | | ByteBuffers.testHeapLoopPutLongSwap | 16 | avgt | 30 | 3.133 | 0.013 | ns/op
-0.034 | | ByteBuffers.testHeapLoopPutShort | 16 | avgt | 30 | 4.184 | 0.046 | ns/op
-0.007 | | ByteBuffers.testHeapLoopPutShortSwap | 16 | avgt | 30 | 4.208 | 0.038 | ns/op
-------------
PR: https://git.openjdk.org/jdk/pull/11755
More information about the nio-dev
mailing list