Skip to content

Commit

Permalink
Optimize filter function performance with copyPositions
Browse files Browse the repository at this point in the history
Before the change:
Benchmark                             (name)  Mode  Cnt   Score   Error  Units
BenchmarkArrayFilter.benchmark        filter  avgt   20  22.543 ± 0.979  ns/op
BenchmarkArrayFilter.benchmarkObject  filter  avgt   20  42.045 ± 2.088  ns/op

After the change:
Benchmark                             (name)  Mode  Cnt   Score   Error  Units
BenchmarkArrayFilter.benchmark        filter  avgt   20  13.327 ± 0.359  ns/op
BenchmarkArrayFilter.benchmarkObject  filter  avgt   20  34.443 ± 1.943  ns/op
  • Loading branch information
hackeryang authored and raunaqmorarka committed Mar 29, 2023
1 parent de458d6 commit 500a04a
Showing 1 changed file with 32 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
package io.trino.operator.scalar;

import io.trino.spi.block.Block;
import io.trino.spi.block.BlockBuilder;
import io.trino.spi.function.Description;
import io.trino.spi.function.ScalarFunction;
import io.trino.spi.function.SqlType;
Expand All @@ -39,19 +38,22 @@ public static Block filterLong(
@SqlType("function(T, boolean)") LongToBooleanFunction function)
{
int positionCount = arrayBlock.getPositionCount();
BlockBuilder resultBuilder = elementType.createBlockBuilder(null, positionCount);
int[] positions = new int[positionCount];
int length = 0;
for (int position = 0; position < positionCount; position++) {
Long input = null;
if (!arrayBlock.isNull(position)) {
input = elementType.getLong(arrayBlock, position);
}

Boolean keep = function.apply(input);
if (TRUE.equals(keep)) {
elementType.appendTo(arrayBlock, position, resultBuilder);
}
positions[length] = position;
length += TRUE.equals(keep) ? 1 : 0;
}
if (positions.length == length) {
return arrayBlock;
}
return resultBuilder.build();
return arrayBlock.copyPositions(positions, 0, length);
}

@TypeParameter("T")
Expand All @@ -63,19 +65,22 @@ public static Block filterDouble(
@SqlType("function(T, boolean)") DoubleToBooleanFunction function)
{
int positionCount = arrayBlock.getPositionCount();
BlockBuilder resultBuilder = elementType.createBlockBuilder(null, positionCount);
int[] positions = new int[positionCount];
int length = 0;
for (int position = 0; position < positionCount; position++) {
Double input = null;
if (!arrayBlock.isNull(position)) {
input = elementType.getDouble(arrayBlock, position);
}

Boolean keep = function.apply(input);
if (TRUE.equals(keep)) {
elementType.appendTo(arrayBlock, position, resultBuilder);
}
positions[length] = position;
length += TRUE.equals(keep) ? 1 : 0;
}
if (positions.length == length) {
return arrayBlock;
}
return resultBuilder.build();
return arrayBlock.copyPositions(positions, 0, length);
}

@TypeParameter("T")
Expand All @@ -87,19 +92,22 @@ public static Block filterBoolean(
@SqlType("function(T, boolean)") BooleanToBooleanFunction function)
{
int positionCount = arrayBlock.getPositionCount();
BlockBuilder resultBuilder = elementType.createBlockBuilder(null, positionCount);
int[] positions = new int[positionCount];
int length = 0;
for (int position = 0; position < positionCount; position++) {
Boolean input = null;
if (!arrayBlock.isNull(position)) {
input = elementType.getBoolean(arrayBlock, position);
}

Boolean keep = function.apply(input);
if (TRUE.equals(keep)) {
elementType.appendTo(arrayBlock, position, resultBuilder);
}
positions[length] = position;
length += TRUE.equals(keep) ? 1 : 0;
}
if (positions.length == length) {
return arrayBlock;
}
return resultBuilder.build();
return arrayBlock.copyPositions(positions, 0, length);
}

@TypeParameter("T")
Expand All @@ -111,18 +119,21 @@ public static Block filterObject(
@SqlType("function(T, boolean)") ObjectToBooleanFunction function)
{
int positionCount = arrayBlock.getPositionCount();
BlockBuilder resultBuilder = elementType.createBlockBuilder(null, positionCount);
int[] positions = new int[positionCount];
int length = 0;
for (int position = 0; position < positionCount; position++) {
Object input = null;
if (!arrayBlock.isNull(position)) {
input = elementType.getObject(arrayBlock, position);
}

Boolean keep = function.apply(input);
if (TRUE.equals(keep)) {
elementType.appendTo(arrayBlock, position, resultBuilder);
}
positions[length] = position;
length += TRUE.equals(keep) ? 1 : 0;
}
if (positions.length == length) {
return arrayBlock;
}
return resultBuilder.build();
return arrayBlock.copyPositions(positions, 0, length);
}
}

0 comments on commit 500a04a

Please sign in to comment.