code: /*
   * Copyright (c) 2016-present, RxJava Contributors.
   *
   * Licensed 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 io.reactivex.rxjava3.core;
  
  import java.util.*;
  import java.util.concurrent.TimeUnit;
  
  import org.openjdk.jmh.annotations.*;
  import org.openjdk.jmh.infra.Blackhole;
  import org.reactivestreams.Publisher;
  
  import io.reactivex.rxjava3.functions.Function;
  
  @BenchmarkMode(Mode.Throughput)
  @Warmup(iterations = 5)
  @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
  @OutputTimeUnit(TimeUnit.SECONDS)
  @Fork(value = 1)
  @State(Scope.Thread)
  public class XMapYPerf {
      @Param({ "1", "10", "100", "1000", "10000", "100000", "1000000" })
      public int times;
  
      Flowable<Integer> flowFlatMapIterable1;
  
      Flowable<Integer> flowFlatMapIterable0;
  
      Flowable<Integer> flowFlatMapFlowable0;
  
      Flowable<Integer> flowFlatMapFlowable1;
  
      Flowable<Integer> flowFlatMapSingle1;
  
      Flowable<Integer> flowFlatMapMaybe1;
  
      Flowable<Integer> flowFlatMapMaybe0;
  
      Completable flowFlatMapCompletable0;
  
      // oooooooooooooooooooooooooooooooooooooooooo
  
      Flowable<Integer> flowFlatMapSingleAsFlow1;
  
      Flowable<Integer> flowFlatMapMaybeAsFlow1;
  
      Flowable<Integer> flowFlatMapMaybeAsFlow0;
  
      Flowable<Integer> flowFlatMapCompletableAsFlow0;
  
      Flowable<Integer> flowFlatMapIterableAsFlow1;
  
      Flowable<Integer> flowFlatMapIterableAsFlow0;
  
      // -----------------------------------------------------------------
  
      Observable<Integer> obsFlatMapIterable0;
  
      Observable<Integer> obsFlatMapIterable1;
  
      Observable<Integer> obsFlatMapObservable0;
  
      Observable<Integer> obsFlatMapObservable1;
  
      Observable<Integer> obsFlatMapSingle1;
  
      Observable<Integer> obsFlatMapMaybe1;
  
      Observable<Integer> obsFlatMapMaybe0;
  
      Completable obsFlatMapCompletable0;
  
      // oooooooooooooooooooooooooooooooooooooooooo
  
      Observable<Integer> obsFlatMapSingleAsObs1;
  
      Observable<Integer> obsFlatMapMaybeAsObs1;
  
      Observable<Integer> obsFlatMapMaybeAsObs0;
  
      Observable<Integer> obsFlatMapCompletableAsObs0;
  
      Observable<Integer> obsFlatMapIterableAsObs1;
  
      Observable<Integer> obsFlatMapIterableAsObs0;
  
      @Setup
      public void setup() {
          Integer[] values = new Integer[times];
          Arrays.fill(values, 777);
  
          Flowable<Integer> fsource = Flowable.fromArray(values);
  
          flowFlatMapFlowable1 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Flowable.just(v);
              }
          });
  
          flowFlatMapFlowable0 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Flowable.empty();
              }
          });
  
          flowFlatMapSingle1 = fsource.flatMapSingle(new Function<Integer, SingleSource<Integer>>() {
              @Override
              public SingleSource<Integer> apply(Integer v) {
                  return Single.just(v);
              }
          });
  
          flowFlatMapMaybe1 = fsource.flatMapMaybe(new Function<Integer, MaybeSource<Integer>>() {
              @Override
              public MaybeSource<Integer> apply(Integer v) {
                  return Maybe.just(v);
              }
          });
  
          flowFlatMapMaybe0 = fsource.flatMapMaybe(new Function<Integer, MaybeSource<Integer>>() {
              @Override
              public MaybeSource<Integer> apply(Integer v) {
                  return Maybe.empty();
              }
          });
  
          flowFlatMapCompletable0 = fsource.flatMapCompletable(new Function<Integer, CompletableSource>() {
              @Override
              public CompletableSource apply(Integer v) {
                  return Completable.complete();
              }
          });
  
          flowFlatMapIterable1 = fsource.flatMapIterable(new Function<Integer, Iterable<Integer>>() {
              @Override
              public Iterable<Integer> apply(Integer v) {
                  return Collections.singletonList(v);
              }
          });
  
          flowFlatMapIterable0 = fsource.flatMapIterable(new Function<Integer, Iterable<Integer>>() {
              @Override
              public Iterable<Integer> apply(Integer v) {
                  return Collections.emptyList();
              }
          });
  
          flowFlatMapSingle1 = fsource.flatMapSingle(new Function<Integer, SingleSource<Integer>>() {
              @Override
              public SingleSource<Integer> apply(Integer v) {
                  return Single.just(v);
              }
          });
  
          flowFlatMapMaybe1 = fsource.flatMapMaybe(new Function<Integer, MaybeSource<Integer>>() {
              @Override
              public MaybeSource<Integer> apply(Integer v) {
                  return Maybe.just(v);
              }
          });
  
          flowFlatMapMaybe0 = fsource.flatMapMaybe(new Function<Integer, MaybeSource<Integer>>() {
              @Override
              public MaybeSource<Integer> apply(Integer v) {
                  return Maybe.empty();
              }
          });
  
          flowFlatMapCompletable0 = fsource.flatMapCompletable(new Function<Integer, CompletableSource>() {
              @Override
              public CompletableSource apply(Integer v) {
                  return Completable.complete();
              }
          });
  
          // ooooooooooooooooooooooooo
  
          flowFlatMapSingleAsFlow1 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Single.just(v).toFlowable();
              }
          });
  
          flowFlatMapMaybeAsFlow1 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Maybe.just(v).toFlowable();
              }
          });
  
          flowFlatMapMaybeAsFlow0 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Maybe.<Integer>empty().toFlowable();
              }
          });
  
          flowFlatMapCompletableAsFlow0 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Completable.complete().toFlowable();
              }
          });
  
          flowFlatMapIterableAsFlow1 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Flowable.fromIterable(Collections.singletonList(v));
              }
          });
  
          flowFlatMapIterableAsFlow0 = fsource.flatMap(new Function<Integer, Publisher<Integer>>() {
              @Override
              public Publisher<Integer> apply(Integer v) {
                  return Flowable.fromIterable(Collections.emptyList());
              }
          });
  
          // -------------------------------------------------------------------
  
          Observable<Integer> osource = Observable.fromArray(values);
  
          obsFlatMapObservable1 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Observable.just(v);
              }
          });
  
          obsFlatMapObservable0 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Observable.empty();
              }
          });
  
          obsFlatMapSingle1 = osource.flatMapSingle(new Function<Integer, SingleSource<Integer>>() {
              @Override
              public SingleSource<Integer> apply(Integer v) {
                  return Single.just(v);
              }
          });
  
          obsFlatMapMaybe1 = osource.flatMapMaybe(new Function<Integer, MaybeSource<Integer>>() {
              @Override
              public MaybeSource<Integer> apply(Integer v) {
                  return Maybe.just(v);
              }
          });
  
          obsFlatMapMaybe0 = osource.flatMapMaybe(new Function<Integer, MaybeSource<Integer>>() {
              @Override
              public MaybeSource<Integer> apply(Integer v) {
                  return Maybe.empty();
              }
          });
  
          obsFlatMapCompletable0 = osource.flatMapCompletable(new Function<Integer, CompletableSource>() {
              @Override
              public CompletableSource apply(Integer v) {
                  return Completable.complete();
              }
          });
  
          obsFlatMapIterable1 = osource.flatMapIterable(new Function<Integer, Iterable<Integer>>() {
              @Override
              public Iterable<Integer> apply(Integer v) {
                  return Collections.singletonList(v);
              }
          });
  
          obsFlatMapIterable0 = osource.flatMapIterable(new Function<Integer, Iterable<Integer>>() {
              @Override
              public Iterable<Integer> apply(Integer v) {
                  return Collections.emptyList();
              }
          });
  
          // ooooooooooooooooooooooooo
  
          obsFlatMapSingleAsObs1 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Single.just(v).toObservable();
              }
          });
  
          obsFlatMapMaybeAsObs1 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Maybe.just(v).toObservable();
              }
          });
  
          obsFlatMapMaybeAsObs0 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Maybe.<Integer>empty().toObservable();
              }
          });
  
          obsFlatMapCompletableAsObs0 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Completable.complete().toObservable();
              }
          });
  
          obsFlatMapIterableAsObs1 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Observable.fromIterable(Collections.singletonList(v));
              }
          });
  
          obsFlatMapIterableAsObs0 = osource.flatMap(new Function<Integer, Observable<Integer>>() {
              @Override
              public Observable<Integer> apply(Integer v) {
                  return Observable.fromIterable(Collections.emptyList());
              }
          });
      }
  
      @Benchmark
      public void flowFlatMapIterable1(Blackhole bh) {
          flowFlatMapIterable1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapIterable0(Blackhole bh) {
          flowFlatMapIterable0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapFlowable0(Blackhole bh) {
          flowFlatMapFlowable0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapFlowable1(Blackhole bh) {
          flowFlatMapFlowable1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapSingle1(Blackhole bh) {
          flowFlatMapSingle1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapMaybe1(Blackhole bh) {
          flowFlatMapMaybe1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapMaybe0(Blackhole bh) {
          flowFlatMapMaybe0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapCompletable0(Blackhole bh) {
          flowFlatMapCompletable0.subscribe(new PerfConsumer(bh));
      }
  
      // oooooooooooooooooooooooooooooooo
  
      @Benchmark
      public void flowFlatMapIterableAsFlow1(Blackhole bh) {
          flowFlatMapIterableAsFlow1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapIterableAsFlow0(Blackhole bh) {
          flowFlatMapIterableAsFlow0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapSingleAsFlow1(Blackhole bh) {
          flowFlatMapSingleAsFlow1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapMaybeAsFlow1(Blackhole bh) {
          flowFlatMapMaybeAsFlow1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapMaybeAsFlow0(Blackhole bh) {
          flowFlatMapMaybeAsFlow0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void flowFlatMapCompletableAsFlow0(Blackhole bh) {
          flowFlatMapCompletableAsFlow0.subscribe(new PerfConsumer(bh));
      }
  
      // --------------------------------------------------------------------------------
  
      @Benchmark
      public void obsFlatMapIterable0(Blackhole bh) {
          obsFlatMapIterable0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapIterable1(Blackhole bh) {
          obsFlatMapIterable1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapObservable0(Blackhole bh) {
          obsFlatMapObservable0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapObservable1(Blackhole bh) {
          obsFlatMapObservable1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapSingle1(Blackhole bh) {
          obsFlatMapSingle1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapMaybe1(Blackhole bh) {
          obsFlatMapMaybe1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapMaybe0(Blackhole bh) {
          obsFlatMapMaybe0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapCompletable0(Blackhole bh) {
          obsFlatMapCompletable0.subscribe(new PerfConsumer(bh));
      }
  
      // oooooooooooooooooooooooooooooooo
  
      @Benchmark
      public void obsFlatMapIterableAsObs1(Blackhole bh) {
          obsFlatMapIterableAsObs1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapIterableAsObs0(Blackhole bh) {
          obsFlatMapIterableAsObs0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapSingleAsObs1(Blackhole bh) {
          obsFlatMapSingleAsObs1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapMaybeAsObs1(Blackhole bh) {
          obsFlatMapMaybeAsObs1.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapMaybeAsObs0(Blackhole bh) {
          obsFlatMapMaybeAsObs0.subscribe(new PerfConsumer(bh));
      }
  
      @Benchmark
      public void obsFlatMapCompletableAsObs0(Blackhole bh) {
          obsFlatMapCompletableAsObs0.subscribe(new PerfConsumer(bh));
      }
  }
  