This is an automated email from the ASF dual-hosted git repository.
yangjie01 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new c2a739fe388a [SPARK-55789][CORE][TESTS] Add a microbenchmark for
`Platform`
c2a739fe388a is described below
commit c2a739fe388a427f01f3d289d2419cc1d2ff40b5
Author: yangjie01 <[email protected]>
AuthorDate: Tue Mar 3 13:24:23 2026 +0800
[SPARK-55789][CORE][TESTS] Add a microbenchmark for `Platform`
### What changes were proposed in this pull request?
This pr aims to add a microbenchmark for `Platform`.
### Why are the changes needed?
`Platform` is a fundamental utility class that is heavily reliant on the
underlying JDK implementation. Adding a microbenchmark allows for better
observation of its performance discrepancies across different JDK versions,
facilitating timely and targeted optimization.
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
- Pass Github Actions
### Was this patch authored or co-authored using generative AI tooling?
No
Closes #54570 from LuciferYang/SPARK-55789.
Lead-authored-by: yangjie01 <[email protected]>
Co-authored-by: LuciferYang <[email protected]>
Signed-off-by: yangjie01 <[email protected]>
---
.../benchmarks/PlatformBenchmark-jdk21-results.txt | 278 ++++++++++
.../benchmarks/PlatformBenchmark-jdk25-results.txt | 278 ++++++++++
core/benchmarks/PlatformBenchmark-results.txt | 278 ++++++++++
.../spark/unsafe/PlatformBenchmarkTestUtils.java | 37 ++
.../apache/spark/unsafe/PlatformBenchmark.scala | 557 +++++++++++++++++++++
5 files changed, 1428 insertions(+)
diff --git a/core/benchmarks/PlatformBenchmark-jdk21-results.txt
b/core/benchmarks/PlatformBenchmark-jdk21-results.txt
new file mode 100644
index 000000000000..ffbe88064475
--- /dev/null
+++ b/core/benchmarks/PlatformBenchmark-jdk21-results.txt
@@ -0,0 +1,278 @@
+================================================================================================
+Platform Byte Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Byte Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putByte: On-heap 65 65
1 1540.3 0.6 1.0X
+putByte: Off-heap 76 76
0 1314.8 0.8 0.9X
+getByte: On-heap 53 53
0 1885.8 0.5 1.2X
+getByte: Off-heap 46 46
0 2170.2 0.5 1.4X
+
+
+================================================================================================
+Platform Short Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Short Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putShort: On-heap 63 63
0 1581.9 0.6 1.0X
+putShort: Off-heap 71 71
0 1408.9 0.7 0.9X
+getShort: On-heap 43 43
0 2343.8 0.4 1.5X
+getShort: Off-heap 50 50
0 1998.5 0.5 1.3X
+
+
+================================================================================================
+Platform Int Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Int Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putInt: On-heap 56 56
0 1781.2 0.6 1.0X
+putInt: Off-heap 53 53
0 1892.8 0.5 1.1X
+getInt: On-heap 35 35
0 2848.5 0.4 1.6X
+getInt: Off-heap 37 38
0 2678.7 0.4 1.5X
+
+
+================================================================================================
+Platform Long Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Long Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putLong: On-heap 69 69
0 1445.7 0.7 1.0X
+putLong: Off-heap 52 53
1 1907.6 0.5 1.3X
+getLong: On-heap 41 42
1 2434.5 0.4 1.7X
+getLong: Off-heap 45 46
1 2242.5 0.4 1.6X
+
+
+================================================================================================
+Platform Float Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Float Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putFloat: On-heap 44 44
0 2274.8 0.4 1.0X
+putFloat: Off-heap 48 48
0 2105.0 0.5 0.9X
+getFloat: On-heap 94 94
0 1068.3 0.9 0.5X
+getFloat: Off-heap 94 94
0 1068.1 0.9 0.5X
+
+
+================================================================================================
+Platform Double Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Double Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putDouble: On-heap 46 47
0 2154.5 0.5 1.0X
+putDouble: Off-heap 50 50
0 2014.0 0.5 0.9X
+getDouble: On-heap 94 95
0 1058.6 0.9 0.5X
+getDouble: Off-heap 95 95
0 1053.9 0.9 0.5X
+
+
+================================================================================================
+Platform Boolean Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Boolean Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putBoolean: On-heap 66 66
0 1509.1 0.7 1.0X
+putBoolean: Off-heap 78 80
7 1289.7 0.8 0.9X
+getBoolean: On-heap 62 62
0 1606.0 0.6 1.1X
+getBoolean: Off-heap 62 62
0 1605.6 0.6 1.1X
+
+
+================================================================================================
+Platform Bulk Operations 4k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 4k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 5.4 186.4 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 4.1 241.4 0.8X
+copyMemory: Off-heap -> Heap 0 0
0 4.4 225.5 0.8X
+copyMemory: Heap -> Heap 0 0
0 4.3 231.4 0.8X
+manual: Heap -> Heap 0 0
0 0.9 1062.9 0.2X
+manual: Off-heap -> Heap 0 0
0 1.0 960.7 0.2X
+setMemory: Off-heap 0 0
0 3.0 336.6 0.6X
+
+
+================================================================================================
+Platform Bulk Operations 16k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 16k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 0.7 1526.9 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 0.7 1336.5 1.1X
+copyMemory: Off-heap -> Heap 0 0
0 0.7 1425.6 1.1X
+copyMemory: Heap -> Heap 0 0
0 0.7 1358.6 1.1X
+manual: Heap -> Heap 0 0
0 0.2 5434.1 0.3X
+manual: Off-heap -> Heap 0 0
0 0.3 3906.2 0.4X
+setMemory: Off-heap 0 0
0 0.8 1293.3 1.2X
+
+
+================================================================================================
+Platform Bulk Operations 256k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 256k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 0.0 26855.1 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 0.0 26615.6 1.0X
+copyMemory: Off-heap -> Heap 0 0
0 0.0 25575.7 1.1X
+copyMemory: Heap -> Heap 0 0
0 0.0 25511.5 1.1X
+manual: Heap -> Heap 1 1
0 0.0 87430.0 0.3X
+manual: Off-heap -> Heap 1 1
0 0.0 62307.2 0.4X
+setMemory: Off-heap 0 0
0 0.0 20416.1 1.3X
+
+
+================================================================================================
+Platform Bulk Operations 1m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 1m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 1 1
0 0.0 144063.6 1.0X
+copyMemory: Heap -> Off-heap 1 1
0 0.0 136948.4 1.1X
+copyMemory: Off-heap -> Heap 1 1
0 0.0 136958.4 1.1X
+copyMemory: Heap -> Heap 1 1
0 0.0 137138.7 1.1X
+manual: Heap -> Heap 3 3
0 0.0 274832.5 0.5X
+manual: Off-heap -> Heap 3 3
0 0.0 250522.1 0.6X
+setMemory: Off-heap 1 1
0 0.0 81296.7 1.8X
+
+
+================================================================================================
+Platform Bulk Operations 8m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 8m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 14 14
0 0.0 1382687.3 1.0X
+copyMemory: Heap -> Off-heap 17 18
0 0.0 1729538.1 0.8X
+copyMemory: Off-heap -> Heap 17 17
0 0.0 1677423.9 0.8X
+copyMemory: Heap -> Heap 17 17
0 0.0 1666798.1 0.8X
+manual: Heap -> Heap 25 26
0 0.0 2509961.4 0.6X
+manual: Off-heap -> Heap 25 26
0 0.0 2499264.5 0.6X
+setMemory: Off-heap 8 10
1 0.0 796434.1 1.7X
+
+
+================================================================================================
+Platform Bulk Operations 32m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 32m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 78 79
1 0.0 7763257.0 1.0X
+copyMemory: Heap -> Off-heap 84 85
1 0.0 8381141.4 0.9X
+copyMemory: Off-heap -> Heap 83 85
1 0.0 8338717.4 0.9X
+copyMemory: Heap -> Heap 84 85
2 0.0 8357496.5 0.9X
+manual: Heap -> Heap 104 107
7 0.0 10358296.5 0.7X
+manual: Off-heap -> Heap 108 110
1 0.0 10802113.1 0.7X
+setMemory: Off-heap 55 57
1 0.0 5479064.0 1.4X
+
+
+================================================================================================
+Platform Memory Allocation 4k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 4k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 7662.8 0.1 0.2X
+
+
+================================================================================================
+Platform Memory Allocation 16k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 16k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 864.3 1.2 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 256k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 256k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 46.2 21.7 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 1m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 1m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 14.1 71.0 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 8m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 8m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 468.6 2.1 1.0X
+freeMemory 0 0
0 333.8 3.0 0.7X
+reallocateMemory: double in size 2 2
0 0.9 1097.5 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 32m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.10+7-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 32m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 475.3 2.1 1.0X
+freeMemory 0 0
0 289.3 3.5 0.6X
+reallocateMemory: double in size 11 11
0 0.2 5503.5 0.0X
+
+
diff --git a/core/benchmarks/PlatformBenchmark-jdk25-results.txt
b/core/benchmarks/PlatformBenchmark-jdk25-results.txt
new file mode 100644
index 000000000000..06a1792a67f0
--- /dev/null
+++ b/core/benchmarks/PlatformBenchmark-jdk25-results.txt
@@ -0,0 +1,278 @@
+================================================================================================
+Platform Byte Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Byte Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putByte: On-heap 61 61
0 1645.1 0.6 1.0X
+putByte: Off-heap 78 78
0 1281.6 0.8 0.8X
+getByte: On-heap 52 52
0 1912.1 0.5 1.2X
+getByte: Off-heap 52 52
0 1909.8 0.5 1.2X
+
+
+================================================================================================
+Platform Short Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Short Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putShort: On-heap 61 62
0 1627.3 0.6 1.0X
+putShort: Off-heap 76 76
0 1317.8 0.8 0.8X
+getShort: On-heap 41 41
0 2420.1 0.4 1.5X
+getShort: Off-heap 50 50
0 1992.3 0.5 1.2X
+
+
+================================================================================================
+Platform Int Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Int Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putInt: On-heap 44 44
0 2260.5 0.4 1.0X
+putInt: Off-heap 56 56
0 1795.5 0.6 0.8X
+getInt: On-heap 34 34
0 2972.8 0.3 1.3X
+getInt: Off-heap 40 40
0 2502.6 0.4 1.1X
+
+
+================================================================================================
+Platform Long Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Long Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putLong: On-heap 68 68
1 1478.1 0.7 1.0X
+putLong: Off-heap 54 54
0 1858.3 0.5 1.3X
+getLong: On-heap 40 41
1 2514.0 0.4 1.7X
+getLong: Off-heap 43 45
1 2308.7 0.4 1.6X
+
+
+================================================================================================
+Platform Float Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Float Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putFloat: On-heap 44 44
0 2262.0 0.4 1.0X
+putFloat: Off-heap 50 50
0 2019.5 0.5 0.9X
+getFloat: On-heap 94 94
0 1068.9 0.9 0.5X
+getFloat: Off-heap 94 94
0 1068.1 0.9 0.5X
+
+
+================================================================================================
+Platform Double Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Double Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putDouble: On-heap 46 47
0 2168.0 0.5 1.0X
+putDouble: Off-heap 52 52
0 1931.2 0.5 0.9X
+getDouble: On-heap 94 94
0 1061.9 0.9 0.5X
+getDouble: Off-heap 95 95
0 1058.1 0.9 0.5X
+
+
+================================================================================================
+Platform Boolean Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Boolean Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putBoolean: On-heap 68 70
5 1469.9 0.7 1.0X
+putBoolean: Off-heap 52 52
0 1929.7 0.5 1.3X
+getBoolean: On-heap 62 62
0 1605.4 0.6 1.1X
+getBoolean: Off-heap 62 62
0 1603.2 0.6 1.1X
+
+
+================================================================================================
+Platform Bulk Operations 4k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 4k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 5.4 186.3 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 4.6 216.4 0.9X
+copyMemory: Off-heap -> Heap 0 0
0 4.0 250.4 0.7X
+copyMemory: Heap -> Heap 0 0
0 4.6 218.4 0.9X
+manual: Heap -> Heap 0 0
0 0.9 1115.0 0.2X
+manual: Off-heap -> Heap 0 0
0 1.0 958.7 0.2X
+setMemory: Off-heap 0 0
0 3.1 321.6 0.6X
+
+
+================================================================================================
+Platform Bulk Operations 16k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 16k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 0.8 1297.4 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 0.7 1374.5 0.9X
+copyMemory: Off-heap -> Heap 0 0
0 0.8 1307.4 1.0X
+copyMemory: Heap -> Heap 0 0
0 0.8 1308.4 1.0X
+manual: Heap -> Heap 0 0
0 0.2 5481.2 0.2X
+manual: Off-heap -> Heap 0 0
0 0.3 3927.3 0.3X
+setMemory: Off-heap 0 0
0 0.8 1286.3 1.0X
+
+
+================================================================================================
+Platform Bulk Operations 256k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 256k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 0.0 28214.6 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 0.0 25715.9 1.1X
+copyMemory: Off-heap -> Heap 0 0
0 0.0 26025.5 1.1X
+copyMemory: Heap -> Heap 0 0
0 0.0 25499.4 1.1X
+manual: Heap -> Heap 1 1
0 0.0 89010.7 0.3X
+manual: Off-heap -> Heap 1 1
0 0.0 64418.9 0.4X
+setMemory: Off-heap 0 0
0 0.0 20724.7 1.4X
+
+
+================================================================================================
+Platform Bulk Operations 1m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 1m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 1 1
0 0.0 106262.8 1.0X
+copyMemory: Heap -> Off-heap 1 1
0 0.0 104618.6 1.0X
+copyMemory: Off-heap -> Heap 1 1
0 0.0 104421.3 1.0X
+copyMemory: Heap -> Heap 1 1
0 0.0 103696.0 1.0X
+manual: Heap -> Heap 3 3
0 0.0 287286.8 0.4X
+manual: Off-heap -> Heap 3 3
0 0.0 254099.0 0.4X
+setMemory: Off-heap 1 1
0 0.0 81383.4 1.3X
+
+
+================================================================================================
+Platform Bulk Operations 8m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 8m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 14 16
1 0.0 1408711.6 1.0X
+copyMemory: Heap -> Off-heap 16 17
1 0.0 1592233.3 0.9X
+copyMemory: Off-heap -> Heap 16 17
0 0.0 1580333.7 0.9X
+copyMemory: Heap -> Heap 16 17
1 0.0 1594253.6 0.9X
+manual: Heap -> Heap 25 25
0 0.0 2473883.8 0.6X
+manual: Off-heap -> Heap 25 26
1 0.0 2500358.3 0.6X
+setMemory: Off-heap 8 13
1 0.0 849445.6 1.7X
+
+
+================================================================================================
+Platform Bulk Operations 32m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 32m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 75 77
1 0.0 7519485.5 1.0X
+copyMemory: Heap -> Off-heap 83 86
2 0.0 8296719.9 0.9X
+copyMemory: Off-heap -> Heap 79 82
2 0.0 7949268.1 0.9X
+copyMemory: Heap -> Heap 78 81
2 0.0 7825109.7 1.0X
+manual: Heap -> Heap 100 101
1 0.0 10000320.7 0.8X
+manual: Off-heap -> Heap 101 105
2 0.0 10118767.2 0.7X
+setMemory: Off-heap 58 62
2 0.0 5778583.5 1.3X
+
+
+================================================================================================
+Platform Memory Allocation 4k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 4k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 6666.7 0.2 0.1X
+
+
+================================================================================================
+Platform Memory Allocation 16k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 16k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 40816.3 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.2X
+reallocateMemory: double in size 0 0
0 713.0 1.4 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 256k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 256k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 40816.3 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.2X
+reallocateMemory: double in size 0 0
0 40.9 24.4 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 1m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 1m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 40816.3 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.2X
+reallocateMemory: double in size 0 0
0 19.5 51.4 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 8m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 8m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 464.1 2.2 1.0X
+freeMemory 0 0
0 329.4 3.0 0.7X
+reallocateMemory: double in size 2 2
0 0.9 1109.9 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 32m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.2+10-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 32m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 463.3 2.2 1.0X
+freeMemory 0 0
0 284.4 3.5 0.6X
+reallocateMemory: double in size 10 10
0 0.2 4779.0 0.0X
+
+
diff --git a/core/benchmarks/PlatformBenchmark-results.txt
b/core/benchmarks/PlatformBenchmark-results.txt
new file mode 100644
index 000000000000..9eb9699df33e
--- /dev/null
+++ b/core/benchmarks/PlatformBenchmark-results.txt
@@ -0,0 +1,278 @@
+================================================================================================
+Platform Byte Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Byte Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putByte: On-heap 63 63
0 1590.5 0.6 1.0X
+putByte: Off-heap 80 80
0 1245.7 0.8 0.8X
+getByte: On-heap 59 59
0 1685.7 0.6 1.1X
+getByte: Off-heap 47 48
1 2112.6 0.5 1.3X
+
+
+================================================================================================
+Platform Short Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Short Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putShort: On-heap 63 63
1 1586.2 0.6 1.0X
+putShort: Off-heap 119 119
0 839.2 1.2 0.5X
+getShort: On-heap 44 44
0 2256.6 0.4 1.4X
+getShort: Off-heap 57 57
0 1761.1 0.6 1.1X
+
+
+================================================================================================
+Platform Int Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Int Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putInt: On-heap 42 42
0 2369.5 0.4 1.0X
+putInt: Off-heap 50 50
0 2000.7 0.5 0.8X
+getInt: On-heap 34 34
0 2941.2 0.3 1.2X
+getInt: Off-heap 49 49
0 2034.2 0.5 0.9X
+
+
+================================================================================================
+Platform Long Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Long Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putLong: On-heap 65 65
0 1546.6 0.6 1.0X
+putLong: Off-heap 48 48
0 2084.7 0.5 1.3X
+getLong: On-heap 40 42
1 2493.5 0.4 1.6X
+getLong: Off-heap 52 52
0 1941.1 0.5 1.3X
+
+
+================================================================================================
+Platform Float Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Float Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putFloat: On-heap 47 47
0 2115.7 0.5 1.0X
+putFloat: Off-heap 63 63
0 1596.2 0.6 0.8X
+getFloat: On-heap 94 94
0 1068.3 0.9 0.5X
+getFloat: Off-heap 94 94
0 1067.6 0.9 0.5X
+
+
+================================================================================================
+Platform Double Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Double Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putDouble: On-heap 49 49
0 2043.5 0.5 1.0X
+putDouble: Off-heap 64 64
0 1562.3 0.6 0.8X
+getDouble: On-heap 94 94
0 1061.5 0.9 0.5X
+getDouble: Off-heap 95 95
0 1057.1 0.9 0.5X
+
+
+================================================================================================
+Platform Boolean Access
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Boolean Access: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+putBoolean: On-heap 78 78
0 1279.0 0.8 1.0X
+putBoolean: Off-heap 76 76
1 1314.5 0.8 1.0X
+getBoolean: On-heap 62 62
0 1604.5 0.6 1.3X
+getBoolean: Off-heap 62 63
0 1601.0 0.6 1.3X
+
+
+================================================================================================
+Platform Bulk Operations 4k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 4k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 5.4 184.3 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 1.6 608.2 0.3X
+copyMemory: Off-heap -> Heap 0 0
0 4.9 202.3 0.9X
+copyMemory: Heap -> Heap 0 0
0 4.7 211.3 0.9X
+manual: Heap -> Heap 0 0
0 0.9 1063.0 0.2X
+manual: Off-heap -> Heap 0 0
0 1.0 960.7 0.2X
+setMemory: Off-heap 0 0
0 1.5 649.2 0.3X
+
+
+================================================================================================
+Platform Bulk Operations 16k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 16k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 0.8 1294.4 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 0.7 1414.7 0.9X
+copyMemory: Off-heap -> Heap 0 0
0 0.8 1287.4 1.0X
+copyMemory: Heap -> Heap 0 0
0 0.8 1286.4 1.0X
+manual: Heap -> Heap 0 0
0 0.2 5439.1 0.2X
+manual: Off-heap -> Heap 0 0
0 0.3 3849.2 0.3X
+setMemory: Off-heap 0 0
0 0.4 2552.7 0.5X
+
+
+================================================================================================
+Platform Bulk Operations 256k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 256k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 0 0
0 0.0 27951.4 1.0X
+copyMemory: Heap -> Off-heap 0 0
0 0.0 27292.1 1.0X
+copyMemory: Off-heap -> Heap 0 0
0 0.0 25880.5 1.1X
+copyMemory: Heap -> Heap 0 0
0 0.0 25672.1 1.1X
+manual: Heap -> Heap 1 1
0 0.0 88010.9 0.3X
+manual: Off-heap -> Heap 1 1
0 0.0 62301.7 0.4X
+setMemory: Off-heap 0 0
0 0.0 40585.0 0.7X
+
+
+================================================================================================
+Platform Bulk Operations 1m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 1m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 1 2
0 0.0 138711.9 1.0X
+copyMemory: Heap -> Off-heap 1 1
0 0.0 104891.6 1.3X
+copyMemory: Off-heap -> Heap 1 1
0 0.0 104430.8 1.3X
+copyMemory: Heap -> Heap 1 1
0 0.0 103958.9 1.3X
+manual: Heap -> Heap 3 3
0 0.0 274934.2 0.5X
+manual: Off-heap -> Heap 3 3
1 0.0 252551.2 0.5X
+setMemory: Off-heap 2 2
0 0.0 162971.4 0.9X
+
+
+================================================================================================
+Platform Bulk Operations 8m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 8m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 15 16
0 0.0 1494501.6 1.0X
+copyMemory: Heap -> Off-heap 17 18
0 0.0 1696782.5 0.9X
+copyMemory: Off-heap -> Heap 17 17
0 0.0 1674377.6 0.9X
+copyMemory: Heap -> Heap 17 17
0 0.0 1665476.9 0.9X
+manual: Heap -> Heap 25 25
0 0.0 2459913.6 0.6X
+manual: Off-heap -> Heap 25 25
0 0.0 2455565.3 0.6X
+setMemory: Off-heap 14 15
0 0.0 1409985.1 1.1X
+
+
+================================================================================================
+Platform Bulk Operations 32m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Bulk Operations 32m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+copyMemory: Off-heap -> Off-heap 77 77
1 0.0 7664570.1 1.0X
+copyMemory: Heap -> Off-heap 84 86
1 0.0 8400167.3 0.9X
+copyMemory: Off-heap -> Heap 81 85
1 0.0 8115112.6 0.9X
+copyMemory: Heap -> Heap 82 84
1 0.0 8232211.9 0.9X
+manual: Heap -> Heap 99 100
1 0.0 9924878.4 0.8X
+manual: Off-heap -> Heap 101 103
1 0.0 10107944.3 0.8X
+setMemory: Off-heap 59 60
1 0.0 5916000.3 1.3X
+
+
+================================================================================================
+Platform Memory Allocation 4k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 4k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 40816.3 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.2X
+reallocateMemory: double in size 0 0
0 5882.4 0.2 0.1X
+
+
+================================================================================================
+Platform Memory Allocation 16k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 16k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 40816.3 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.2X
+reallocateMemory: double in size 0 0
0 1296.2 0.8 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 256k Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 256k Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 45.6 21.9 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 1m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 1m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 50000.0 0.0 1.0X
+freeMemory 0 0
0 50000.0 0.0 1.0X
+reallocateMemory: double in size 0 0
0 13.5 73.9 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 8m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 8m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 400.9 2.5 1.0X
+freeMemory 0 0
0 386.8 2.6 1.0X
+reallocateMemory: double in size 3 3
0 0.7 1384.4 0.0X
+
+
+================================================================================================
+Platform Memory Allocation 32m Ints
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.18+8-LTS on Linux 6.14.0-1017-azure
+AMD EPYC 7763 64-Core Processor
+Memory Allocation 32m Ints: Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+allocateMemory 0 0
0 476.5 2.1 1.0X
+freeMemory 0 0
0 294.9 3.4 0.6X
+reallocateMemory: double in size 11 11
0 0.2 5518.7 0.0X
+
+
diff --git
a/core/src/test/java/org/apache/spark/unsafe/PlatformBenchmarkTestUtils.java
b/core/src/test/java/org/apache/spark/unsafe/PlatformBenchmarkTestUtils.java
new file mode 100644
index 000000000000..44a5b81b50d3
--- /dev/null
+++ b/core/src/test/java/org/apache/spark/unsafe/PlatformBenchmarkTestUtils.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.unsafe;
+
+public class PlatformBenchmarkTestUtils {
+
+ /**
+ * Copies memory from the source (either on-heap or off-heap) to the
destination integer array
+ * using a manual loop. This method mimics the implementation of manual
memory copying found
+ * in {@link org.apache.spark.sql.execution.vectorized.OnHeapColumnVector}.
+ *
+ * @param src The source object (null for off-heap memory).
+ * @param srcOffset The initial offset in the source memory.
+ * @param dst The destination integer array.
+ * @param count The number of integers to copy.
+ */
+ public static void copyToIntArrayManual(Object src, long srcOffset, int[]
dst, int count) {
+ for (int i = 0; i < count; ++i, srcOffset += 4) {
+ dst[i] = Platform.getInt(src, srcOffset);
+ }
+ }
+}
diff --git
a/core/src/test/scala/org/apache/spark/unsafe/PlatformBenchmark.scala
b/core/src/test/scala/org/apache/spark/unsafe/PlatformBenchmark.scala
new file mode 100644
index 000000000000..d314fe76fb31
--- /dev/null
+++ b/core/src/test/scala/org/apache/spark/unsafe/PlatformBenchmark.scala
@@ -0,0 +1,557 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.unsafe
+
+import org.apache.spark.benchmark.{Benchmark, BenchmarkBase}
+
+/**
+ * Benchmark for o.a.s.unsafe.Platform.
+ * To run this benchmark:
+ * {{{
+ * 1. without sbt:
+ * bin/spark-submit --class <this class> <spark core test jar>
+ * 2. build/sbt "core/Test/runMain <this class>"
+ * 3. generate result:
+ * SPARK_GENERATE_BENCHMARK_FILES=1 build/sbt "core/Test/runMain <this
class>"
+ * Results will be written to "benchmarks/PlatformBenchmark-results.txt".
+ * }}}
+ */
+object PlatformBenchmark extends BenchmarkBase {
+
+ override def runBenchmarkSuite(mainArgs: Array[String]): Unit = {
+ val count4k = 4 * 1024 // 4k elements
+ val str4k = "4k"
+ val count16k = 16 * 1024 // 16k elements
+ val str16k = "16k"
+ val count256k = 256 * 1024 // 256k elements
+ val str256k = "256k"
+ val count1m = 1 * 1024 * 1024 // 1M elements
+ val str1m = "1m"
+ val count8m = 8 * 1024 * 1024 // 8M elements
+ val str8m = "8m"
+ val count32m = 32 * 1024 * 1024 // 32M elements
+ val str32m = "32m"
+ val iterations = 100000000L // 100M ops
+
+ runByteAccess(count8m, iterations)
+ runShortAccess(count8m, iterations)
+ runIntAccess(count8m, iterations)
+ runLongAccess(count8m, iterations)
+ runFloatAccess(count8m, iterations)
+ runDoubleAccess(count8m, iterations)
+ runBooleanAccess(count8m, iterations)
+
+ val counts = Seq((count4k, str4k), (count16k, str16k), (count256k,
str256k),
+ (count1m, str1m), (count8m, str8m), (count32m, str32m))
+ counts.foreach { case (count, str) =>
+ runBulkOperations(count, str)
+ }
+ counts.foreach { case (count, str) =>
+ runMemoryAllocation(count, str)
+ }
+ }
+
+ private def runByteAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 1
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Byte](count.toInt)
+ val onHeapOffset = Platform.BYTE_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Byte Access") {
+ val benchmark = new Benchmark("Byte Access", iterations, output =
output)
+
+ benchmark.addCase("putByte: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putByte(onHeapArray, onHeapOffset + (i & mask), i.toByte)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putByte: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putByte(null, address + (i & mask), i.toByte)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getByte: On-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getByte(onHeapArray, onHeapOffset + (i & mask))
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getByte: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getByte(null, address + (i & mask))
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runShortAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 2
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Short](count.toInt)
+ val onHeapOffset = Platform.SHORT_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Short Access") {
+ val benchmark = new Benchmark("Short Access", iterations, output =
output)
+
+ benchmark.addCase("putShort: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putShort(onHeapArray, onHeapOffset + (i & mask) * 2,
i.toShort)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putShort: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putShort(null, address + (i & mask) * 2, i.toShort)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getShort: On-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getShort(onHeapArray, onHeapOffset + (i & mask) *
2)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getShort: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getShort(null, address + (i & mask) * 2)
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runIntAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 4
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Int](count.toInt)
+ val onHeapOffset = Platform.INT_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Int Access") {
+ val benchmark = new Benchmark("Int Access", iterations, output =
output)
+
+ benchmark.addCase("putInt: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putInt(onHeapArray, onHeapOffset + (i & mask) * 4,
i.toInt)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putInt: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putInt(null, address + (i & mask) * 4, i.toInt)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getInt: On-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getInt(onHeapArray, onHeapOffset + (i & mask) * 4)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getInt: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getInt(null, address + (i & mask) * 4)
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runLongAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 8
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Long](count.toInt)
+ val onHeapOffset = Platform.LONG_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Long Access") {
+ val benchmark = new Benchmark("Long Access", iterations, output =
output)
+
+ benchmark.addCase("putLong: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putLong(onHeapArray, onHeapOffset + (i & mask) * 8, i)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putLong: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putLong(null, address + (i & mask) * 8, i)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getLong: On-heap") { _ =>
+ var i = 0L
+ var sum = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getLong(onHeapArray, onHeapOffset + (i & mask) * 8)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getLong: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getLong(null, address + (i & mask) * 8)
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runFloatAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 4
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Float](count.toInt)
+ val onHeapOffset = Platform.FLOAT_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Float Access") {
+ val benchmark = new Benchmark("Float Access", iterations, output =
output)
+
+ benchmark.addCase("putFloat: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putFloat(onHeapArray, onHeapOffset + (i & mask) * 4,
i.toFloat)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putFloat: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putFloat(null, address + (i & mask) * 4, i.toFloat)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getFloat: On-heap") { _ =>
+ var i = 0L
+ var sum = 0.0f
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getFloat(onHeapArray, onHeapOffset + (i & mask) *
4)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getFloat: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0.0f
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getFloat(null, address + (i & mask) * 4)
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runDoubleAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 8
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Double](count.toInt)
+ val onHeapOffset = Platform.DOUBLE_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Double Access") {
+ val benchmark = new Benchmark("Double Access", iterations, output =
output)
+
+ benchmark.addCase("putDouble: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putDouble(onHeapArray, onHeapOffset + (i & mask) * 8,
i.toDouble)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putDouble: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putDouble(null, address + (i & mask) * 8, i.toDouble)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getDouble: On-heap") { _ =>
+ var i = 0L
+ var sum = 0.0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getDouble(onHeapArray, onHeapOffset + (i & mask) *
8)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getDouble: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0.0
+ val mask = count - 1
+ while (i < iterations) {
+ sum += Platform.getDouble(null, address + (i & mask) * 8)
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runBooleanAccess(count: Long, iterations: Long): Unit = {
+ val size = count * 1
+ val address = Platform.allocateMemory(size)
+ val onHeapArray = new Array[Boolean](count.toInt)
+ val onHeapOffset = Platform.BOOLEAN_ARRAY_OFFSET
+ try {
+ runBenchmark("Platform Boolean Access") {
+ val benchmark = new Benchmark("Boolean Access", iterations, output =
output)
+
+ benchmark.addCase("putBoolean: On-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putBoolean(onHeapArray, onHeapOffset + (i & mask), (i &
1) == 0)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("putBoolean: Off-heap") { _ =>
+ var i = 0L
+ val mask = count - 1
+ while (i < iterations) {
+ Platform.putBoolean(null, address + (i & mask), (i & 1) == 0)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getBoolean: On-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ if (Platform.getBoolean(onHeapArray, onHeapOffset + (i & mask))) {
+ sum += 1
+ }
+ i += 1
+ }
+ }
+
+ benchmark.addCase("getBoolean: Off-heap") { _ =>
+ var i = 0L
+ var sum = 0
+ val mask = count - 1
+ while (i < iterations) {
+ if (Platform.getBoolean(null, address + (i & mask))) {
+ sum += 1
+ }
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runBulkOperations(count: Long, countStr: String): Unit = {
+ val size = count * 4
+ val address = Platform.allocateMemory(size)
+ val srcArray = new Array[Int](count.toInt)
+ val dstArray = new Array[Int](count.toInt)
+ val srcByteArray = new Array[Byte](size.toInt)
+ var j = 0
+ while (j < count) {
+ srcArray(j) = j.toInt
+ j += 1
+ }
+ Platform.copyMemory(srcArray, Platform.INT_ARRAY_OFFSET, srcByteArray,
+ Platform.BYTE_ARRAY_OFFSET, size)
+ try {
+ runBenchmark(s"Platform Bulk Operations $countStr Ints") {
+ val benchmark = new Benchmark(s"Bulk Operations $countStr Ints", 10,
output = output)
+
+ benchmark.addCase("copyMemory: Off-heap -> Off-heap") { _ =>
+ val dst = Platform.allocateMemory(size)
+ var i = 0L
+ while (i < 10) {
+ Platform.copyMemory(null, address, null, dst, size)
+ i += 1
+ }
+ Platform.freeMemory(dst)
+ }
+
+ benchmark.addCase("copyMemory: Heap -> Off-heap") { _ =>
+ var i = 0L
+ while (i < 10) {
+ Platform.copyMemory(srcArray, Platform.INT_ARRAY_OFFSET, null,
address, size)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("copyMemory: Off-heap -> Heap") { _ =>
+ var i = 0L
+ while (i < 10) {
+ Platform.copyMemory(null, address, dstArray,
Platform.INT_ARRAY_OFFSET, size)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("copyMemory: Heap -> Heap") { _ =>
+ var i = 0L
+ while (i < 10) {
+ Platform.copyMemory(
+ srcByteArray, Platform.BYTE_ARRAY_OFFSET, dstArray,
Platform.INT_ARRAY_OFFSET, size)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("manual: Heap -> Heap") { _ =>
+ var i = 0L
+ while (i < 10) {
+ PlatformBenchmarkTestUtils.copyToIntArrayManual(
+ srcArray, Platform.INT_ARRAY_OFFSET, dstArray, count.toInt)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("manual: Off-heap -> Heap") { _ =>
+ var i = 0L
+ while (i < 10) {
+ PlatformBenchmarkTestUtils.copyToIntArrayManual(
+ null, address, dstArray, count.toInt)
+ i += 1
+ }
+ }
+
+ benchmark.addCase("setMemory: Off-heap") { _ =>
+ var i = 0L
+ while (i < 10) {
+ Platform.setMemory(address, 0, size)
+ i += 1
+ }
+ }
+ benchmark.run()
+ }
+ } finally {
+ Platform.freeMemory(address)
+ }
+ }
+
+ private def runMemoryAllocation(count: Int, countStr: String): Unit = {
+ val size = count * 4
+ runBenchmark(s"Platform Memory Allocation $countStr Ints") {
+ val benchmark = new Benchmark(s"Memory Allocation $countStr Ints", 2000,
output = output)
+
+ benchmark.addTimerCase(s"allocateMemory") { timer =>
+ timer.startTiming()
+ val addr = Platform.allocateMemory(size)
+ timer.stopTiming()
+ Platform.freeMemory(addr)
+ }
+
+ benchmark.addTimerCase(s"freeMemory") { timer =>
+ val addr = Platform.allocateMemory(size)
+ timer.startTiming()
+ Platform.freeMemory(addr)
+ timer.stopTiming()
+ }
+
+ benchmark.addTimerCase(s"reallocateMemory: double in size") { timer =>
+ var addr = Platform.allocateMemory(size)
+ timer.startTiming()
+ addr = Platform.reallocateMemory(addr, size, size * 2)
+ timer.stopTiming()
+ Platform.freeMemory(addr)
+ }
+ benchmark.run()
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]