mirror of https://github.com/rusefi/lua.git
small optimization in `sort'
This commit is contained in:
parent
ad3816d0d1
commit
f01e6c6f1d
88
lbaselib.c
88
lbaselib.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lbaselib.c,v 1.8 2000/10/02 20:10:55 roberto Exp roberto $
|
** $Id: lbaselib.c,v 1.9 2000/10/05 12:14:08 roberto Exp roberto $
|
||||||
** Basic library
|
** Basic library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -433,75 +433,78 @@ static int luaB_tremove (lua_State *L) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static void swap (lua_State *L, int i, int j) {
|
static void set2 (lua_State *L, int i, int j) {
|
||||||
lua_rawgeti(L, 1, i);
|
|
||||||
lua_rawgeti(L, 1, j);
|
|
||||||
lua_rawseti(L, 1, i);
|
lua_rawseti(L, 1, i);
|
||||||
lua_rawseti(L, 1, j);
|
lua_rawseti(L, 1, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sort_comp (lua_State *L, int n, int r) {
|
static int sort_comp (lua_State *L, int a, int b) {
|
||||||
/* WARNING: the caller (auxsort) must ensure stack space */
|
/* WARNING: the caller (auxsort) must ensure stack space */
|
||||||
int res;
|
|
||||||
if (!lua_isnil(L, 2)) { /* function? */
|
if (!lua_isnil(L, 2)) { /* function? */
|
||||||
|
int res;
|
||||||
lua_pushvalue(L, 2);
|
lua_pushvalue(L, 2);
|
||||||
if (r) {
|
lua_pushvalue(L, a-1); /* -1 to compensate function */
|
||||||
lua_rawgeti(L, 1, n); /* a[n] */
|
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
|
||||||
lua_pushvalue(L, -3); /* pivot */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lua_pushvalue(L, -2); /* pivot */
|
|
||||||
lua_rawgeti(L, 1, n); /* a[n] */
|
|
||||||
}
|
|
||||||
lua_rawcall(L, 2, 1);
|
lua_rawcall(L, 2, 1);
|
||||||
res = !lua_isnil(L, -1);
|
res = !lua_isnil(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
else { /* a < b? */
|
else /* a < b? */
|
||||||
lua_rawgeti(L, 1, n); /* a[n] */
|
return lua_lessthan(L, a, b);
|
||||||
if (r)
|
|
||||||
res = lua_lessthan(L, -1, -2);
|
|
||||||
else
|
|
||||||
res = lua_lessthan(L, -2, -1);
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auxsort (lua_State *L, int l, int u) {
|
static void auxsort (lua_State *L, int l, int u) {
|
||||||
while (l < u) { /* for tail recursion */
|
while (l < u) { /* for tail recursion */
|
||||||
int i, j;
|
int i, j;
|
||||||
luaL_checkstack(L, 4, "array too large");
|
|
||||||
/* sort elements a[l], a[(l+u)/2] and a[u] */
|
/* sort elements a[l], a[(l+u)/2] and a[u] */
|
||||||
|
lua_rawgeti(L, 1, l);
|
||||||
lua_rawgeti(L, 1, u);
|
lua_rawgeti(L, 1, u);
|
||||||
if (sort_comp(L, l, 0)) /* a[u] < a[l]? */
|
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
|
||||||
swap(L, l, u);
|
set2(L, l, u); /* swap a[l] - a[u] */
|
||||||
lua_pop(L, 1);
|
else
|
||||||
|
lua_pop(L, 2);
|
||||||
if (u-l == 1) break; /* only 2 elements */
|
if (u-l == 1) break; /* only 2 elements */
|
||||||
i = (l+u)/2;
|
i = (l+u)/2;
|
||||||
lua_rawgeti(L, 1, i); /* Pivot = a[i] */
|
lua_rawgeti(L, 1, i);
|
||||||
if (sort_comp(L, l, 0)) /* a[i]<a[l]? */
|
lua_rawgeti(L, 1, l);
|
||||||
swap(L, l, i);
|
if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
|
||||||
|
set2(L, i, l);
|
||||||
else {
|
else {
|
||||||
if (sort_comp(L, u, 1)) /* a[u]<a[i]? */
|
lua_pop(L, 1); /* remove a[l] */
|
||||||
swap(L, i, u);
|
lua_rawgeti(L, 1, u);
|
||||||
|
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
|
||||||
|
set2(L, i, u);
|
||||||
|
else
|
||||||
|
lua_pop(L, 2);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1); /* pop old a[i] */
|
|
||||||
if (u-l == 2) break; /* only 3 elements */
|
if (u-l == 2) break; /* only 3 elements */
|
||||||
lua_rawgeti(L, 1, i); /* Pivot */
|
lua_rawgeti(L, 1, i); /* Pivot */
|
||||||
swap(L, i, u-1); /* put median element as pivot (a[u-1]) */
|
lua_pushvalue(L, -1);
|
||||||
/* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
|
lua_rawgeti(L, 1, u-1);
|
||||||
|
set2(L, i, u-1);
|
||||||
|
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
|
||||||
i = l; j = u-1;
|
i = l; j = u-1;
|
||||||
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
|
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
|
||||||
/* repeat i++ until a[i] >= P */
|
/* repeat ++i until a[i] >= P */
|
||||||
while (sort_comp(L, ++i, 1))
|
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
|
||||||
if (i>u) lua_error(L, "invalid order function for sorting");
|
if (i>u) lua_error(L, "invalid order function for sorting");
|
||||||
/* repeat j-- until a[j] <= P */
|
lua_pop(L, 1); /* remove a[i] */
|
||||||
while (sort_comp(L, --j, 0))
|
}
|
||||||
|
/* repeat --j until a[j] <= P */
|
||||||
|
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
|
||||||
if (j<l) lua_error(L, "invalid order function for sorting");
|
if (j<l) lua_error(L, "invalid order function for sorting");
|
||||||
if (j<i) break;
|
lua_pop(L, 1); /* remove a[j] */
|
||||||
swap(L, i, j);
|
}
|
||||||
|
if (j<i) {
|
||||||
|
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
set2(L, i, j);
|
||||||
}
|
}
|
||||||
swap(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
|
lua_rawgeti(L, 1, u-1);
|
||||||
|
lua_rawgeti(L, 1, i);
|
||||||
|
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
|
||||||
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
|
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
|
||||||
/* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
|
/* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */
|
||||||
if (i-l < u-i) {
|
if (i-l < u-i) {
|
||||||
|
@ -510,7 +513,6 @@ static void auxsort (lua_State *L, int l, int u) {
|
||||||
else {
|
else {
|
||||||
j=i+1; i=u; u=j-2;
|
j=i+1; i=u; u=j-2;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1); /* remove pivot from stack */
|
|
||||||
auxsort(L, j, i); /* call recursively the smaller one */
|
auxsort(L, j, i); /* call recursively the smaller one */
|
||||||
} /* repeat the routine for the larger one */
|
} /* repeat the routine for the larger one */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue