Является ли монадическое программирование на Java 8 медленнее? Ниже мой тест (используется правая привязка, которая создает новые экземпляры для каждого вычисления). Настоятельная версия в 1000 раз быстрее. Как программировать monadicaly в Java8, получая сопоставимую производительность?
Main.java
public class Main {
public static void main(String args[]){
Main m = new Main();
m.work();
m.work2();
}
public void work(){
final long start = System.nanoTime();
final Either<Throwable,Integer> result =
Try(this::getInput).flatMap((s) ->
Try(this::getInput).flatMap((s2) ->
parseInt(s).flatMap((i) ->
parseInt(s2).map((i2) ->
i + i2
))));
final long end = System.nanoTime();
result.map(this::println).leftMap(this::println);
System.out.println((end-start)/1000+"us to execute");
}
public void work2(){
Object result;
final long start = System.nanoTime();
try {
final String s = getInput();
final String s2 = getInput();
final int i = parzeInt(s);
final int i2 = parzeInt(s2);
result = i + i2;
}catch(Throwable t){
result=t;
}
final long end = System.nanoTime();
println(result);
System.out.println((end-start)/1000+"us to execute");
}
public <A> A println(final A a){
System.out.println(a);
return a;
}
public String getInput(){
final Integer value = new Random().nextInt();
if(value % 2 == 0) return "Surprise!!!";
return value+"";
}
public Either<Throwable,Integer> parseInt(final String s){
try{
return Either.right(Integer.parseInt(s));
}catch(final Throwable t){
return Either.left(t);
}
}
public Integer parzeInt(final String s){
return Integer.parseInt(s);
}
}
Either.java
public abstract class Either<L,R>
{
public static <L,R> Either<L,R> left(final L l){
return new Left(l);
}
public static <L,R> Either<L,R> right(final R r){
return new Right(r);
}
public static<L,R> Either<L,R> toEither(final Optional<R> oR,final L l){
return oR.isPresent() ? right(oR.get()) : left(l);
}
public static <R> Either<Throwable,R> Try(final Supplier<R> sr){
try{
return right(sr.get());
}catch(Throwable t){
return left(t);
}
}
public abstract <R2> Either<L,R2> flatMap(final Function<R,Either<L,R2>> f);
public abstract <R2> Either<L,R2> map(final Function<R,R2> f);
public abstract <L2> Either<L2,R> leftMap(final Function<L,L2> f);
public abstract Either<R,L> swap();
public static class Left<L,R> extends Either<L,R> {
final L l;
private Left(final L l){
this.l=l;
}
public <R2> Either<L,R2> flatMap(final Function<R,Either<L,R2>> f){
return (Either<L,R2>)this;
}
public <R2> Either<L,R2> map(final Function<R,R2> f){
return (Either<L,R2>)this;
}
public <L2> Either<L2,R> leftMap(final Function<L,L2> f){
return new Left(f.apply(l));
}
public Either<R,L> swap(){
return new Right(l);
}
}
public static class Right<L,R> extends Either<L,R> {
final R r;
private Right(final R r){
this.r=r;
}
public <R2> Either<L,R2> flatMap(final Function<R,Either<L,R2>> f){
return f.apply(r);
}
public <R2> Either<L,R2> map(final Function<R,R2> f){
return new Right(f.apply(r));
}
public <L2> Either<L2,R> leftMap(final Function<L,L2> f){
return (Either<L2,R>)this;
}
public Either<R,L> swap(){
return new Left(r);
}
}
}