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]

Reply via email to