This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fury.git
The following commit(s) were added to refs/heads/main by this push:
new 33eef02c perf(java): optimize map copy perf (#1767)
33eef02c is described below
commit 33eef02cfefc2a824418230df034b697e440e63f
Author: Shawn Yang <[email protected]>
AuthorDate: Sat Jul 27 16:18:55 2024 +0800
perf(java): optimize map copy perf (#1767)
## What does this PR do?
optimize map copy perf and add benchmark
## Related issues
Closes #1744
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fury/issues/new/choose) describing the
need to do so and update the document if necessary.
-->
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
```
Benchmark (bufferType) (references) Mode Cnt
Score Error Units
CopyBenchmark.fury_copy_int_map array false thrpt 3
1779502.276 ± 2305262.034 ops/s
CopyBenchmark.fury_copy_string_map array false thrpt 3
1845474.980 ± 2072340.777 ops/s
CopyBenchmark.kryo_copy_int_map array false thrpt 3
625471.456 ± 289827.215 ops/s
CopyBenchmark.kryo_copy_string_map array false thrpt 3
649970.300 ± 404700.716 ops/s
Benchmark (bufferType) (references) Mode Cnt
Score Error Units
CopyBenchmark.fury_copy_int_map array false thrpt 3
2023724.754 ± 2067096.856 ops/s
CopyBenchmark.fury_copy_string_map array false thrpt 3
1979796.679 ± 593560.983 ops/s
CopyBenchmark.kryo_copy_int_map array false thrpt 3
569146.293 ± 461667.597 ops/s
CopyBenchmark.kryo_copy_string_map array false thrpt 3
591048.755 ± 669110.894 ops/s
```
---
.../org/apache/fury/benchmark/CopyBenchmark.java | 32 +++++++++++++++++++++-
.../java/org/apache/fury/benchmark/data/Data.java | 18 ++++++++++++
.../org/apache/fury/benchmark/state/KryoState.java | 3 ++
.../collection/AbstractMapSerializer.java | 19 ++++++++++++-
4 files changed, 70 insertions(+), 2 deletions(-)
diff --git
a/java/benchmark/src/main/java/org/apache/fury/benchmark/CopyBenchmark.java
b/java/benchmark/src/main/java/org/apache/fury/benchmark/CopyBenchmark.java
index 1940871f..90f7025e 100644
--- a/java/benchmark/src/main/java/org/apache/fury/benchmark/CopyBenchmark.java
+++ b/java/benchmark/src/main/java/org/apache/fury/benchmark/CopyBenchmark.java
@@ -42,10 +42,40 @@ public class CopyBenchmark {
return state.kryo.copy(state.object);
}
+ @Benchmark
+ public Object fury_copy_string_map(FuryState.DataState state) {
+ return state.fury.copy(state.data.stringMap);
+ }
+
+ @Benchmark
+ public Object fury_copy_int_map(FuryState.DataState state) {
+ return state.fury.copy(state.data.intMap);
+ }
+
+ @Benchmark
+ public Object kryo_copy_string_map(KryoState.DataState state) {
+ return state.kryo.copy(state.data.stringMap);
+ }
+
+ @Benchmark
+ public Object kryo_copy_int_map(KryoState.DataState state) {
+ return state.kryo.copy(state.data.intMap);
+ }
+
+ @Benchmark
+ public Object fury_copy_list(FuryState.DataState state) {
+ return state.fury.copy(state.data.intList);
+ }
+
+ @Benchmark
+ public Object kryo_copy_list(KryoState.DataState state) {
+ return state.kryo.copy(state.data.intList);
+ }
+
public static void main(String[] args) throws IOException {
if (args.length == 0) {
String commandLine =
- "org.apache.fury.*CopyBenchmark.* -f 1 -wi 3 -i 3 -t 1 -w 2s -r 2s
-rf csv "
+ "org.apache.fury.*CopyBenchmark.*map -f 1 -wi 3 -i 3 -t 1 -w 2000s
-r 2s -rf csv "
+ "-p bufferType=array -p references=false";
System.out.println(commandLine);
args = commandLine.split(" ");
diff --git
a/java/benchmark/src/main/java/org/apache/fury/benchmark/data/Data.java
b/java/benchmark/src/main/java/org/apache/fury/benchmark/data/Data.java
index 09f59542..b66309ae 100644
--- a/java/benchmark/src/main/java/org/apache/fury/benchmark/data/Data.java
+++ b/java/benchmark/src/main/java/org/apache/fury/benchmark/data/Data.java
@@ -19,6 +19,10 @@
package org.apache.fury.benchmark.data;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.fury.util.StringUtils;
public class Data {
@@ -93,4 +97,18 @@ public class Data {
}
return StringUtils.random(strLength);
}
+
+ public List<String> stringList = new ArrayList<>();
+ public List<Integer> intList = new ArrayList<>();
+ public Map<String, String> stringMap = new HashMap<>();
+ public Map<Integer, Integer> intMap = new HashMap<>();
+
+ {
+ for (int i = 0; i < 20; i++) {
+ stringList.add("hello, " + i);
+ intList.add(i);
+ stringMap.put("key" + i, "value" + i);
+ intMap.put(i, i * 2);
+ }
+ }
}
diff --git
a/java/benchmark/src/main/java/org/apache/fury/benchmark/state/KryoState.java
b/java/benchmark/src/main/java/org/apache/fury/benchmark/state/KryoState.java
index b773caeb..83678772 100644
---
a/java/benchmark/src/main/java/org/apache/fury/benchmark/state/KryoState.java
+++
b/java/benchmark/src/main/java/org/apache/fury/benchmark/state/KryoState.java
@@ -26,6 +26,7 @@ import
com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer;
import com.esotericsoftware.kryo.unsafe.UnsafeByteBufferInput;
import com.esotericsoftware.kryo.unsafe.UnsafeByteBufferOutput;
import java.util.ArrayList;
+import java.util.HashMap;
import org.apache.fury.benchmark.IntsSerializationSuite;
import org.apache.fury.benchmark.LongStringSerializationSuite;
import org.apache.fury.benchmark.LongsSerializationSuite;
@@ -85,6 +86,8 @@ public class KryoState {
kryo.setRegistrationRequired(registerClass);
kryo.register(int[].class);
kryo.register(long[].class);
+ kryo.register(ArrayList.class);
+ kryo.register(HashMap.class);
}
}
diff --git
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
index a488402c..620f1426 100644
---
a/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
+++
b/java/fury-core/src/main/java/org/apache/fury/serializer/collection/AbstractMapSerializer.java
@@ -29,6 +29,7 @@ import org.apache.fury.collection.Tuple2;
import org.apache.fury.memory.MemoryBuffer;
import org.apache.fury.reflect.ReflectionUtils;
import org.apache.fury.reflect.TypeRef;
+import org.apache.fury.resolver.ClassInfo;
import org.apache.fury.resolver.ClassInfoHolder;
import org.apache.fury.resolver.ClassResolver;
import org.apache.fury.resolver.RefResolver;
@@ -417,8 +418,24 @@ public abstract class AbstractMapSerializer<T> extends
Serializer<T> {
}
protected <K, V> void copyEntry(Map<K, V> originMap, Map<K, V> newMap) {
+ ClassResolver classResolver = fury.getClassResolver();
for (Map.Entry<K, V> entry : originMap.entrySet()) {
- newMap.put(fury.copyObject(entry.getKey()),
fury.copyObject(entry.getValue()));
+ K key = entry.getKey();
+ if (key != null) {
+ ClassInfo classInfo = classResolver.getClassInfo(key.getClass(),
keyClassInfoWriteCache);
+ if (!classInfo.getSerializer().isImmutable()) {
+ key = fury.copyObject(key, classInfo.getClassId());
+ }
+ }
+ V value = entry.getValue();
+ if (value != null) {
+ ClassInfo classInfo =
+ classResolver.getClassInfo(value.getClass(),
valueClassInfoWriteCache);
+ if (!classInfo.getSerializer().isImmutable()) {
+ value = fury.copyObject(value, classInfo.getClassId());
+ }
+ }
+ newMap.put(key, value);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]