From da819e05e521cb89f0dade116ee87bc550f18f46 Mon Sep 17 00:00:00 2001 From: Wenlei Xie Date: Tue, 17 Dec 2019 15:04:50 -0800 Subject: [PATCH] Optimize array_join by supporting PROVIDED_BLOCKBUILDER convention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Benchmark shows over 10% improvements. Before ``` Benchmark Mode Cnt Score Error Units BenchmarkArrayJoin.benchmark avgt 60 152.954 ± 1.246 ns/op ``` After ``` Benchmark Mode Cnt Score Error Units BenchmarkArrayJoin.benchmark avgt 60 134.558 ± 2.078 ns/op ``` --- .../presto/operator/scalar/ArrayJoin.java | 121 +++++++++++++++--- 1 file changed, 100 insertions(+), 21 deletions(-) diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java index a1e88d1910866..24ed2b6754f53 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayJoin.java @@ -18,6 +18,8 @@ import com.facebook.presto.metadata.FunctionManager; import com.facebook.presto.metadata.SqlScalarFunction; import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.ArgumentProperty; +import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.ReturnPlaceConvention; +import com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.ScalarImplementationChoice; import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.PageBuilder; import com.facebook.presto.spi.PrestoException; @@ -46,6 +48,7 @@ import static com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.ArgumentProperty.valueTypeArgumentProperty; import static com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.NullConvention.RETURN_NULL_ON_NULL; import static com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.NullConvention.USE_BOXED_TYPE; +import static com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation.ReturnPlaceConvention.PROVIDED_BLOCKBUILDER; import static com.facebook.presto.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR; import static com.facebook.presto.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT; import static com.facebook.presto.spi.function.Signature.typeVariable; @@ -64,15 +67,25 @@ public final class ArrayJoin private static final TypeSignature VARCHAR_TYPE_SIGNATURE = VARCHAR.getTypeSignature(); private static final String FUNCTION_NAME = "array_join"; private static final String DESCRIPTION = "Concatenates the elements of the given array using a delimiter and an optional string to replace nulls"; - private static final MethodHandle METHOD_HANDLE = methodHandle( + + private static final MethodHandle METHOD_HANDLE_STACK = methodHandle( ArrayJoin.class, - "arrayJoin", + "arrayJoinStack", MethodHandle.class, Object.class, ConnectorSession.class, Block.class, Slice.class); + private static final MethodHandle METHOD_HANDLE_PROVIDED_BLOCK = methodHandle( + ArrayJoin.class, + "arrayJoinProvidedBlock", + MethodHandle.class, + ConnectorSession.class, + BlockBuilder.class, + Block.class, + Slice.class); + private static final MethodHandle GET_BOOLEAN = methodHandle(Type.class, "getBoolean", Block.class, int.class); private static final MethodHandle GET_DOUBLE = methodHandle(Type.class, "getDouble", Block.class, int.class); private static final MethodHandle GET_LONG = methodHandle(Type.class, "getLong", Block.class, int.class); @@ -83,9 +96,9 @@ public final class ArrayJoin public static class ArrayJoinWithNullReplacement extends SqlScalarFunction { - private static final MethodHandle METHOD_HANDLE = methodHandle( + private static final MethodHandle METHOD_HANDLE_STACK = methodHandle( ArrayJoin.class, - "arrayJoin", + "arrayJoinStack", MethodHandle.class, Object.class, ConnectorSession.class, @@ -93,6 +106,16 @@ public static class ArrayJoinWithNullReplacement Slice.class, Slice.class); + private static final MethodHandle METHOD_HANDLE_PROVIDED_BLOCK = methodHandle( + ArrayJoin.class, + "arrayJoinProvidedBlock", + MethodHandle.class, + ConnectorSession.class, + BlockBuilder.class, + Block.class, + Slice.class, + Slice.class); + public ArrayJoinWithNullReplacement() { super(new Signature( @@ -126,7 +149,12 @@ public String getDescription() @Override public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionManager functionManager) { - return specializeArrayJoin(boundVariables.getTypeVariables(), functionManager, ImmutableList.of(false, false, false), METHOD_HANDLE); + return specializeArrayJoin( + boundVariables.getTypeVariables(), + functionManager, + ImmutableList.of(false, false, false), + METHOD_HANDLE_STACK, + METHOD_HANDLE_PROVIDED_BLOCK); } } @@ -169,10 +197,20 @@ public String getDescription() @Override public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionManager functionManager) { - return specializeArrayJoin(boundVariables.getTypeVariables(), functionManager, ImmutableList.of(false, false), METHOD_HANDLE); + return specializeArrayJoin( + boundVariables.getTypeVariables(), + functionManager, + ImmutableList.of(false, false), + METHOD_HANDLE_STACK, + METHOD_HANDLE_PROVIDED_BLOCK); } - private static BuiltInScalarFunctionImplementation specializeArrayJoin(Map types, FunctionManager functionManager, List nullableArguments, MethodHandle methodHandle) + private static BuiltInScalarFunctionImplementation specializeArrayJoin( + Map types, + FunctionManager functionManager, + List nullableArguments, + MethodHandle methodHandleStack, + MethodHandle methodHandleProvidedBlock) { Type type = types.get("T"); List argumentProperties = nullableArguments.stream() @@ -185,7 +223,7 @@ private static BuiltInScalarFunctionImplementation specializeArrayJoin(Map