MartijnVisser commented on code in PR #126:
URL: https://github.com/apache/flink-benchmarks/pull/126#discussion_r4392936059


##########
src/main/java/org/apache/flink/benchmark/SinkUpsertMaterializerBenchmark.java:
##########
@@ -48,172 +53,84 @@
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
 import org.openjdk.jmh.annotations.TearDown;
-import org.openjdk.jmh.runner.Runner;
-import org.openjdk.jmh.runner.RunnerException;
-import org.openjdk.jmh.runner.options.OptionsBuilder;
-import org.openjdk.jmh.runner.options.VerboseMode;
 
-import java.nio.charset.StandardCharsets;
 import java.util.Objects;
 import java.util.Random;
 
 import static 
org.apache.flink.table.runtime.util.StreamRecordUtils.deleteRecord;
 import static 
org.apache.flink.table.runtime.util.StreamRecordUtils.insertRecord;
-import static org.apache.flink.util.Preconditions.checkState;
 
 /**
- * Benchmark for {@link SinkUpsertMaterializer}.
+ * Benchmark for {@link SinkUpsertMaterializer} and {@link 
SinkUpsertMaterializerV2}.
  *
- * <p>It inserts a fixed number of records (inserts and deletes) in a loop and 
measures the time it
- * takes to handle all the records. It uses a test harness, not the full Flink 
job.
+ * <p>It uses a test harness, not the full Flink job. All records share the 
same stream key. The
+ * setup fills the state of that key with {@code historyLength} rows; each 
invocation then inserts
+ * one row and retracts the oldest one, so the history length stays constant 
during the measurement.
  *
  * <p>The benchmark has the following parameters:
  *
  * <ul>
- *   <li>total number of records - fixed to 10K; all records are inserted 
under the same stream key
+ *   <li>sumVersion: V1/V2 (V2 with the default state strategy)
  *   <li>hasUpsertKey: true/false
- *   <li>stateBackend type: HEAP/RocksDB
- *   <li>payload size - fixed to 100 bytes; bigger payload degrades faster on 
RocksDB
- *   <li>retractPercentage, retractDelay - how many records to retract, and 
from which record to
- *       start retracting; both parameters control how frequently retraction 
happens and how long
- *       the history is. Retraction is performed from the middle of the list. 
Retraction is
- *       inefficient in the current implementation on long lists.
+ *   <li>stateBackend: HEAP/ROCKSDB
+ *   <li>historyLength: number of rows kept for the stream key; longer 
histories make retractions
+ *       more expensive
+ *   <li>payloadSize: fixed to 20; a bigger payload amplifies inefficiencies, 
mostly on RocksDB
  * </ul>
- *
- * <p>Results on M3Pro:
- *
- * <pre>{@code
- * Benchmark                            (hasUpsertKey)  (payloadSize)  
(retractDelay)  (retractPercentage)  (stateBackend)  (sumVersion)   Mode  Cnt   
  Score   Error   Units
- * SinkUpsertMaterializerBenchmark.run           false            100          
     1                  100            HEAP            V1  thrpt       4138.808 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
     1                  100         ROCKSDB            V1  thrpt        284.055 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
    10                  100            HEAP            V1  thrpt       3729.824 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
    10                  100         ROCKSDB            V1  thrpt        205.047 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
   100                  100            HEAP            V1  thrpt       4137.591 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
   100                  100         ROCKSDB            V1  thrpt         80.406 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
   200                  100            HEAP            V1  thrpt       1886.574 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
   200                  100         ROCKSDB            V1  thrpt         30.935 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
  1000                  100            HEAP            V1  thrpt        546.826 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run           false            100          
  1000                  100         ROCKSDB            V1  thrpt          7.081 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
     1                  100            HEAP            V1  thrpt       4006.263 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
     1                  100         ROCKSDB            V1  thrpt        297.556 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
    10                  100            HEAP            V1  thrpt       3240.089 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
    10                  100         ROCKSDB            V1  thrpt        209.375 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
   100                  100            HEAP            V1  thrpt       2131.445 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
   100                  100         ROCKSDB            V1  thrpt         78.209 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
   200                  100            HEAP            V1  thrpt        652.936 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
   200                  100         ROCKSDB            V1  thrpt         29.674 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
  1000                  100            HEAP            V1  thrpt        118.567 
         ops/ms
- * SinkUpsertMaterializerBenchmark.run            true            100          
  1000                  100         ROCKSDB            V1  thrpt          6.426 
         ops/ms
- * }</pre>
  */
-@OperationsPerInvocation(value = 
SinkUpsertMaterializerBenchmark.RECORDS_PER_INVOCATION)
-@SuppressWarnings("ConstantValue")
 public class SinkUpsertMaterializerBenchmark extends BenchmarkBase {
 
     private static final int STREAM_KEY = 0;
 
-    public static void main(String[] args) throws RunnerException {
-        new Runner(
-                        new OptionsBuilder()
-                                .verbosity(VerboseMode.NORMAL)
-                                .include(
-                                        ".*"
-                                                + 
SinkUpsertMaterializerBenchmark.class
-                                                        .getCanonicalName()
-                                                + ".*")
-                                .build())
-                .run();
-    }
-
     @Benchmark
-    public void run(SumBmState state) throws Exception {
-        for (long record = 0; record < state.numRecordsTotal; record++) {
-            state.harness.processElement(insertRecord(record, STREAM_KEY, 
state.payload));
-            if (state.shouldRetract(record)) {
-                state.harness.processElement(
-                        deleteRecord(record - state.retractOffset, STREAM_KEY, 
state.payload));
-            }
-        }
+    @OperationsPerInvocation(2)
+    public void sinkUpsertMaterializer(SumBmState state) throws Exception {
+        long record = state.nextRecord++;
+        state.harness.processElement(insertRecord(record, STREAM_KEY, 
state.payload));
+        state.harness.processElement(
+                deleteRecord(record - state.historyLength, STREAM_KEY, 
state.payload));
     }
 
-    protected static final int RECORDS_PER_INVOCATION = 10_000;
-
     @State(Scope.Thread)
     public static class SumBmState {
 
+        @Param({"V1", "V2"})
+        public SumVersion sumVersion;
+
         @Param({"false", "true"})
         public boolean hasUpsertKey;
 
         @Param({"HEAP", "ROCKSDB"})
         public SumStateBackend stateBackend;
 
-        public int numRecordsTotal;
+        @Param({"1", "500"})
+        public int historyLength;
 
-        // larger payload amplifies any inefficiencies but slows down the 
benchmark; mostly affects
-        // rocksdb
         @Param({"20"})
         public int payloadSize;
 
-        // lower retraction percentage implies longer history, making 
retractions even harder
-        // (unless percentage = 0)
-        @Param("100")
-        public int retractPercentage;
-
-        // higher retraction delay leaves longer history, making retractions 
even harder (unless
-        // percentage = 0)
-        // for automated runs, reduce the run time (and the data points) to 
the most common cases
-        @Param({"1", "1000"})
-        // for comparison, the following values might be useful:
-        // @Param({"1", "10", "100", "200", "1000"})
-        public int retractDelay;
-
-        // the lower the value, the closer to the end of the list is the 
element to retract, the
-        // harder for V1 to find the element
-        public long retractOffset;
-
         public String payload;
 
-        public KeyedOneInputStreamOperatorTestHarness<RowData, RowData, 
RowData> harness;
-
-        @Setup(Level.Invocation)
-        public void initSumBmState() throws Exception {
-            harness = getHarness(createSum(hasUpsertKey), stateBackend);
-            payload = generatePayload(payloadSize);
-            numRecordsTotal = RECORDS_PER_INVOCATION;
-            retractOffset = (1 + retractDelay) / 2;

Review Comment:
   It now retracts the middle row. #106 hit the oldest row too, since 
`retractPercentage` 100 skips `retractDelay`. LEGACY on HEAP without an upsert 
key at 500 rows drops from 9850 to 2435 ops/ms.
   



##########
src/main/java/org/apache/flink/benchmark/SinkUpsertMaterializerBenchmark.java:
##########
@@ -230,21 +147,46 @@ private static 
KeyedOneInputStreamOperatorTestHarness<RowData, RowData, RowData>
                         materializer, rowDataSelector, 
rowDataSelector.getProducedType());
         testHarness.getExecutionConfig().setMaxParallelism(2048);
         testHarness.setStateBackend(stateBackend.create(true));
-        testHarness.setOutputCreator(ign -> new BlackHoleOutput()); // 
requires change in Flink
+        testHarness.setOutputCreator(ign -> new BlackHoleOutput());
         testHarness.open();
         return testHarness;
     }
 
-    private static OneInputStreamOperator<RowData, RowData> createSum(boolean 
hasUpsertKey) {
-        StateTtlConfig ttlConfig = StateConfigUtil.createTtlConfig(0); // no 
ttl
-        RowType physicalRowType = RowType.of(types);
-        int[] inputUpsertKey = hasUpsertKey ? new int[] {UPSERT_KEY_POS} : 
null;
-        return new SinkUpsertMaterializer(
-                ttlConfig,
-                InternalSerializers.create(physicalRowType),
-                equalizer(),
-                hasUpsertKey ? upsertEqualizer() : null,
-                inputUpsertKey);
+    public enum SumVersion {
+        V1 {
+            @Override
+            OneInputStreamOperator<RowData, RowData> create(boolean 
hasUpsertKey) {
+                return SinkUpsertMaterializer.create(
+                        TTL_CONFIG,
+                        RowType.of(types),
+                        equalizer(),
+                        hasUpsertKey ? upsertEqualizer() : null,
+                        upsertKey(hasUpsertKey));
+            }
+        },
+        V2 {
+            @Override
+            OneInputStreamOperator<RowData, RowData> create(boolean 
hasUpsertKey) {
+                return SinkUpsertMaterializerV2.create(
+                        RowType.of(types),
+                        equalizer(),
+                        hasUpsertKey ? upsertEqualizer() : null,
+                        hashFunction(),
+                        hasUpsertKey ? upsertHashFunction() : null,
+                        upsertKey(hasUpsertKey),
+                        SequencedMultiSetStateConfig.defaults(
+                                TimeDomain.PROCESSING_TIME, TTL_CONFIG));

Review Comment:
   I've added them, configured as `StreamExecSink` does with the default 
adaptive thresholds. ADAPTIVE stays on VALUE at 1 row and on MAP at 500. That 
doubles its nightly time to about 35 minutes.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to