Polishing.

Introduce empty constants to reduce allocations.

See #3193
Original pull request: #3194
This commit is contained in:
Mark Paluch
2025-02-04 15:45:28 +01:00
parent db382681a8
commit 3969be03c9
4 changed files with 67 additions and 10 deletions

View File

@@ -24,11 +24,26 @@ import org.springframework.util.ObjectUtils;
* {@link Vector} implementation based on {@code double} array.
*
* @author Mark Paluch
* @author Christoph Strobl
* @since 3.5
*/
class DoubleVector implements Vector {
private final double[] v;
static final DoubleVector EMPTY = new DoubleVector(new double[0]) {
@Override
public float[] toFloatArray() {
return FloatVector.EMPTY.v;
}
@Override
public double[] toDoubleArray() {
return this.v;
}
};
final double[] v;
DoubleVector(double[] v) {
this.v = v;
@@ -40,7 +55,7 @@ class DoubleVector implements Vector {
static Vector copy(double[] v) {
if (v.length == 0) {
return new DoubleVector(new double[0]);
return EMPTY;
}
return new DoubleVector(Arrays.copyOf(v, v.length));
@@ -52,7 +67,7 @@ class DoubleVector implements Vector {
static Vector copy(Collection<? extends Number> v) {
if (v.isEmpty()) {
return new DoubleVector(new double[0]);
return EMPTY;
}
double[] copy = new double[v.size()];
@@ -101,9 +116,11 @@ class DoubleVector implements Vector {
if (this == o) {
return true;
}
if (!(o instanceof DoubleVector that)) {
return false;
}
return ObjectUtils.nullSafeEquals(v, that.v);
}

View File

@@ -24,11 +24,26 @@ import org.springframework.util.ObjectUtils;
* {@link Vector} implementation based on {@code float} array.
*
* @author Mark Paluch
* @author Christoph Strobl
* @since 3.5
*/
class FloatVector implements Vector {
private final float[] v;
static final FloatVector EMPTY = new FloatVector(new float[0]) {
@Override
public float[] toFloatArray() {
return this.v;
}
@Override
public double[] toDoubleArray() {
return DoubleVector.EMPTY.v;
}
};
final float[] v;
FloatVector(float[] v) {
this.v = v;
@@ -40,7 +55,7 @@ class FloatVector implements Vector {
static Vector copy(float[] v) {
if (v.length == 0) {
return new FloatVector(new float[0]);
return EMPTY;
}
return new FloatVector(Arrays.copyOf(v, v.length));
@@ -52,7 +67,7 @@ class FloatVector implements Vector {
static Vector copy(Collection<? extends Number> v) {
if (v.isEmpty()) {
return new FloatVector(new float[0]);
return EMPTY;
}
float[] copy = new float[v.size()];
@@ -101,9 +116,11 @@ class FloatVector implements Vector {
if (this == o) {
return true;
}
if (!(o instanceof FloatVector that)) {
return false;
}
return ObjectUtils.nullSafeEquals(v, that.v);
}

View File

@@ -25,10 +25,25 @@ import org.springframework.util.ObjectUtils;
* {@link Vector} implementation based on {@link Number} array.
*
* @author Mark Paluch
* @author Christoph Strobl
* @since 3.5
*/
class NumberVector implements Vector {
static final NumberVector EMPTY = new NumberVector(new Number[0]) {
@Override
public float[] toFloatArray() {
return FloatVector.EMPTY.v;
}
@Override
public double[] toDoubleArray() {
return DoubleVector.EMPTY.v;
}
};
private final Number[] v;
NumberVector(Number[] v) {
@@ -43,7 +58,7 @@ class NumberVector implements Vector {
static Vector copy(Number[] v) {
if (v.length == 0) {
return new NumberVector(new Number[0]);
return EMPTY;
}
return new NumberVector(Arrays.copyOf(v, v.length));
@@ -55,7 +70,7 @@ class NumberVector implements Vector {
static Vector copy(Collection<? extends Number> v) {
if (v.isEmpty()) {
return new NumberVector(new Number[0]);
return EMPTY;
}
return new NumberVector(v.toArray(Number[]::new));
@@ -74,6 +89,7 @@ class NumberVector implements Vector {
return Number.class;
}
}
return candidate;
}
@@ -115,9 +131,11 @@ class NumberVector implements Vector {
if (this == o) {
return true;
}
if (!(o instanceof NumberVector that)) {
return false;
}
return ObjectUtils.nullSafeEquals(v, that.v);
}

View File

@@ -75,8 +75,9 @@ public interface Vector {
static Vector of(Collection<? extends Number> values) {
Assert.notNull(values, "Vector values must not be null");
if(values.isEmpty()) {
return NumberVector.copy(new Number[0]);
if (values.isEmpty()) {
return NumberVector.EMPTY;
}
Class<?> cet = CollectionUtils.findCommonElementType(values);
@@ -152,6 +153,8 @@ public interface Vector {
* <p>
* Conversion to {@code float} can incorporate loss of precision or result in values with a slight offset due to data
* type conversion if the source is not a {@code float} array.
* <p>
* Note that Vectors using quantization or binary representations may not be convertible to a {@code float} array.
*
* @return a new {@code float} array representing the vector point.
*/
@@ -163,6 +166,8 @@ public interface Vector {
* <p>
* Conversion to {@code double} can incorporate loss of precision or result in values with a slight offset due to data
* type conversion if the source is not a {@code double} array.
* <p>
* Note that Vectors using quantization or binary representations may not be convertible to a {@code double} array.
*
* @return a new {@code double} array representing the vector point.
*/