Skip to content

Commit

Permalink
Optimize array_contains functions
Browse files Browse the repository at this point in the history
Improve runtime performance on `array_contains()`, `array_scontains()` and `array_contains_ic()` by iterating over the array values whenever possible, rather than creating a keyset to iterate over and calling the getter to get all values.
  • Loading branch information
Pieter12345 committed Jan 17, 2025
1 parent 63ff249 commit 03de1f1
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/laytonsmith/core/constructs/CArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ public Version since() {
@Override
public Iterator<Mixed> iterator() {
if(associativeMode) {
throw new RuntimeException("iterator() cannot be called on an associative array");
return associativeArray.values().iterator();
} else {
return array.iterator();
}
Expand Down
33 changes: 32 additions & 1 deletion src/main/java/com/laytonsmith/core/constructs/CByteArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,20 @@ public void removeValues(Mixed construct) {

@Override
public Iterator<Mixed> iterator() {
throw new CREUnsupportedOperationException("Iterating a byte array is not supported.", getTarget());
return new Iterator<Mixed>() {

private int index = 0;

@Override
public boolean hasNext() {
return this.index <= maxValue;
}

@Override
public Mixed next() {
return new CInt(data.get(this.index++), Target.UNKNOWN);
}
};
}

@Override
Expand Down Expand Up @@ -696,6 +709,24 @@ protected SortedMap<String, Mixed> getAssociativeArray() {
throw new Error("This error should not happen. Please report this bug to the developers");
}

@Override
public Iterator<Mixed> iterator() {
return new Iterator<Mixed>() {

private int index = 0;

@Override
public boolean hasNext() {
return this.index <= backing.length;
}

@Override
public Mixed next() {
return new CInt(backing[this.index++], Target.UNKNOWN);
}
};
}

@Override
public String docs() {
return "A read-only subclass of array, which is used to make reading byte arrays more efficient.";
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/laytonsmith/core/constructs/CSlice.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,43 @@ public int size() {
};
}

@Override
public Iterator<Mixed> iterator() {
if(start <= finish) {
return new Iterator<Mixed>() {

private long current = start;
private long last = finish;

@Override
public boolean hasNext() {
return this.current <= this.last;
}

@Override
public Mixed next() {
return new CInt(this.current++, Target.UNKNOWN);
}
};
} else {
return new Iterator<Mixed>() {

private long current = start;
private long last = finish;

@Override
public boolean hasNext() {
return this.current >= this.last;
}

@Override
public Mixed next() {
return new CInt(this.current--, Target.UNKNOWN);
}
};
}
}

@Override
public long size() {
return size;
Expand Down
42 changes: 33 additions & 9 deletions src/main/java/com/laytonsmith/core/functions/ArrayHandling.java
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,17 @@ public Mixed exec(Target t, Environment env, Mixed... args) throws CancelCommand
CArray ca = ArgumentValidation.getArray(args[0], t);
aa = ca;
}
for(Mixed key : aa.keySet()) {
if(new equals().exec(t, env, aa.get(key, t), args[1]).getBoolean()) {
return CBoolean.TRUE;
if(aa instanceof CArray ca) {
for(Mixed val : ca) {
if(new equals().exec(t, env, val, args[1]).getBoolean()) {
return CBoolean.TRUE;
}
}
} else {
for(Mixed key : aa.keySet()) {
if(new equals().exec(t, env, aa.get(key, t), args[1]).getBoolean()) {
return CBoolean.TRUE;
}
}
}
return CBoolean.FALSE;
Expand Down Expand Up @@ -822,9 +830,17 @@ public Mixed exec(Target t, Environment environment, Mixed... args) throws Confi
} else {
aa = ArgumentValidation.getArray(args[0], t);
}
for(Mixed key : aa.keySet()) {
if(new equals_ic().exec(t, environment, aa.get(key, t), args[1]).getBoolean()) {
return CBoolean.TRUE;
if(aa instanceof CArray ca) {
for(Mixed val : ca) {
if(new equals_ic().exec(t, environment, val, args[1]).getBoolean()) {
return CBoolean.TRUE;
}
}
} else {
for(Mixed key : aa.keySet()) {
if(new equals_ic().exec(t, environment, aa.get(key, t), args[1]).getBoolean()) {
return CBoolean.TRUE;
}
}
}
return CBoolean.FALSE;
Expand Down Expand Up @@ -876,9 +892,17 @@ public Mixed exec(Target t, Environment env, Mixed... args) throws CancelCommand
} else {
aa = ArgumentValidation.getArray(args[0], t);
}
for(Mixed key : aa.keySet()) {
if(new sequals().exec(t, env, aa.get(key, t), args[1]).getBoolean()) {
return CBoolean.TRUE;
if(aa instanceof CArray ca) {
for(Mixed val : ca) {
if(new sequals().exec(t, env, val, args[1]).getBoolean()) {
return CBoolean.TRUE;
}
}
} else {
for(Mixed key : aa.keySet()) {
if(new sequals().exec(t, env, aa.get(key, t), args[1]).getBoolean()) {
return CBoolean.TRUE;
}
}
}
return CBoolean.FALSE;
Expand Down

0 comments on commit 03de1f1

Please sign in to comment.