Speed up table.sort.

This commit is contained in:
Enyby
2019-11-03 14:03:53 +02:00
parent 53bd4bf71f
commit 99f21b6277

View File

@@ -789,17 +789,21 @@ public class LuaTable extends LuaValue implements Metatable {
if (m_metatable != null && m_metatable.useWeakValues()) { if (m_metatable != null && m_metatable.useWeakValues()) {
dropWeakArrayValues(); dropWeakArrayValues();
} }
LuaValue[] array = this.array;
int n = array.length; int n = array.length;
while ( n > 0 && array[n-1] == null ) while ( n > 0 && array[n-1] == null )
--n; --n;
if ( n > 1 ) if ( n > 1 )
heapSort(n, comparator); heapSort(n, comparator.isnil() ? null : comparator);
} }
private void heapSort(int count, LuaValue cmpfunc) { private void heapSort(int count, LuaValue cmpfunc) {
heapify(count, cmpfunc); heapify(count, cmpfunc);
LuaValue[] array = this.array;
for ( int end=count-1; end>0; ) { for ( int end=count-1; end>0; ) {
swap(end, 0); LuaValue a = array[end]; // swap(end, 0)
array[end] = array[0];
array[0] = a;
siftDown(0, --end, cmpfunc); siftDown(0, --end, cmpfunc);
} }
} }
@@ -810,12 +814,15 @@ public class LuaTable extends LuaValue implements Metatable {
} }
private void siftDown(int start, int end, LuaValue cmpfunc) { private void siftDown(int start, int end, LuaValue cmpfunc) {
LuaValue[] array = this.array;
for ( int root=start; root*2+1 <= end; ) { for ( int root=start; root*2+1 <= end; ) {
int child = root*2+1; int child = root*2+1;
if (child < end && compare(child, child + 1, cmpfunc)) if (child < end && compare(child, child + 1, cmpfunc))
++child; ++child;
if (compare(root, child, cmpfunc)) { if (compare(root, child, cmpfunc)) {
swap(root, child); LuaValue a = array[root]; // swap(root, child)
array[root] = array[child];
array[child] = a;
root = child; root = child;
} else } else
return; return;
@@ -824,6 +831,8 @@ public class LuaTable extends LuaValue implements Metatable {
private boolean compare(int i, int j, LuaValue cmpfunc) { private boolean compare(int i, int j, LuaValue cmpfunc) {
LuaValue a, b; LuaValue a, b;
LuaValue[] array = this.array;
Metatable m_metatable = this.m_metatable;
if (m_metatable == null) { if (m_metatable == null) {
a = array[i]; a = array[i];
b = array[j]; b = array[j];
@@ -833,19 +842,13 @@ public class LuaTable extends LuaValue implements Metatable {
} }
if ( a == null || b == null ) if ( a == null || b == null )
return false; return false;
if ( ! cmpfunc.isnil() ) { if ( cmpfunc != null ) {
return cmpfunc.call(a,b).toboolean(); return cmpfunc.call(a,b).toboolean();
} else { } else {
return a.lt_b(b); return a.lt_b(b);
} }
} }
private void swap(int i, int j) {
LuaValue a = array[i];
array[i] = array[j];
array[j] = a;
}
/** This may be deprecated in a future release. /** This may be deprecated in a future release.
* It is recommended to count via iteration over next() instead * It is recommended to count via iteration over next() instead
* @return count of keys in the table * @return count of keys in the table