[INTERPRETER]
* OPT: Native array optimizations are better. For arrays with one dimension, reading is about 70% faster than gambas2, and writing 40% faster. * OPT: Collection array accessors were optimized too. Reading is about 50% faster and writing 60% faster. Be careful: only the array accessors were optimized, not the full hash table access, which is the slower part of the process. git-svn-id: svn://localhost/gambas/trunk@1036 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
6ac9fbe05b
commit
7cc9986bda
@ -3748,3 +3748,4 @@ PUBLIC SUB DrawTitle(hForm AS Object)
|
||||
hForm.Title = sTitle '& " - " & Project.Name
|
||||
|
||||
END
|
||||
|
||||
|
@ -85,11 +85,11 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: DataControl.class:76 DataView.class:195
|
||||
#: DataControl.class:76 DataView.class:198
|
||||
msgid "True"
|
||||
msgstr "Vrai"
|
||||
|
||||
#: DataControl.class:77 DataView.class:195
|
||||
#: DataControl.class:77 DataView.class:198
|
||||
msgid "False"
|
||||
msgstr "Faux"
|
||||
|
||||
@ -137,34 +137,34 @@ msgstr "Suivant"
|
||||
msgid "End"
|
||||
msgstr "Fin"
|
||||
|
||||
#: FMain.class:102
|
||||
#: FMain.class:104
|
||||
msgid "Id"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:107
|
||||
#: FMain.class:109
|
||||
msgid "Color"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:112
|
||||
#: FMain.class:114
|
||||
msgid "First Name"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:117
|
||||
#: FMain.class:119
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:122
|
||||
#: FMain.class:124
|
||||
msgid "Birth"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:127
|
||||
#: FMain.class:129
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:132
|
||||
#: FMain.class:134
|
||||
msgid "Salary"
|
||||
msgstr ""
|
||||
|
||||
#: FMain.class:137
|
||||
#: FMain.class:139
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
@ -7,7 +7,7 @@ Library=gb.form
|
||||
Library=gb.db
|
||||
Library=gb.db.form
|
||||
Authors=Benoît Minisini
|
||||
Environment="GB_GUI=gb.gtk"
|
||||
Environment="GB_GUI="
|
||||
TabSize=2
|
||||
Translate=1
|
||||
Language=en
|
||||
|
@ -124,7 +124,7 @@ void *GB_ArrayGet(GB_ARRAY array, int index);
|
||||
|
||||
void GB_CollectionNew(GB_COLLECTION *col, int mode);
|
||||
int GB_CollectionCount(GB_COLLECTION col);
|
||||
void GB_CollectionSet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *value);
|
||||
int GB_CollectionSet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *value);
|
||||
int GB_CollectionGet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *value);
|
||||
int GB_CollectionEnum(GB_COLLECTION col, GB_VARIANT *value, char **key, int *len);
|
||||
|
||||
|
@ -100,8 +100,9 @@ static void *get_data(CARRAY *_object, int index)
|
||||
return (void *)((char *)(THIS->data) + index * TYPE_sizeof_memory(THIS->type));
|
||||
}
|
||||
|
||||
#define get_data_multi CARRAY_get_data_multi
|
||||
|
||||
static void *get_data_multi(CARRAY *_object, GB_INTEGER *arg, int nparam)
|
||||
void *CARRAY_get_data_multi(CARRAY *_object, GB_INTEGER *arg, int nparam)
|
||||
{
|
||||
int index;
|
||||
|
||||
|
@ -68,5 +68,6 @@ void CARRAY_split(CARRAY *_object, const char *str, int lstr, const char *sep, c
|
||||
void CARRAY_reverse(void *_object, void *_param);
|
||||
void CARRAY_get_value(CARRAY *_object, int index, VALUE *value);
|
||||
#define CARRAY_invert(_array) CARRAY_reverse(_array, NULL)
|
||||
void *CARRAY_get_data_multi(CARRAY *_object, GB_INTEGER *arg, int nparam);
|
||||
|
||||
#endif
|
||||
|
@ -59,7 +59,6 @@ static void collection_free(CCOLLECTION *col)
|
||||
HASH_TABLE_delete(&col->hash_table);
|
||||
}
|
||||
|
||||
|
||||
static void *collection_get_key(CCOLLECTION *col, const char *key, int len)
|
||||
{
|
||||
if (!key || !*key)
|
||||
@ -344,7 +343,7 @@ int GB_CollectionCount(GB_COLLECTION col)
|
||||
return HASH_TABLE_size(((CCOLLECTION *)col)->hash_table);
|
||||
}
|
||||
|
||||
void GB_CollectionSet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *value)
|
||||
int GB_CollectionSet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *value)
|
||||
{
|
||||
VARIANT *data;
|
||||
|
||||
@ -353,9 +352,11 @@ void GB_CollectionSet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *v
|
||||
else
|
||||
{
|
||||
data = (VARIANT *)collection_add_key((CCOLLECTION *)col, key, len);
|
||||
if (data)
|
||||
GB_StoreVariant(value, data);
|
||||
if (!data)
|
||||
return TRUE;
|
||||
GB_StoreVariant(value, data);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int GB_CollectionGet(GB_COLLECTION col, const char *key, int len, GB_VARIANT *value)
|
||||
|
@ -247,8 +247,8 @@ typedef
|
||||
unsigned mmapped : 1; /* mmap() was used to load the class */
|
||||
unsigned swap : 1; /* class endianness was swapped */
|
||||
unsigned enum_static : 1; /* if class enumeration is static */
|
||||
//unsigned quick_array : 1; /* array accessor optimizations can apply */
|
||||
unsigned _flag : 3; /* 30 */
|
||||
unsigned quick_array : 2; /* array accessor optimization type */
|
||||
unsigned _flag : 1; /* 30 */
|
||||
|
||||
short n_desc; /* 32 number of descriptions */
|
||||
CLASS_DESC_SYMBOL *table; /* 36 class description */
|
||||
@ -258,8 +258,8 @@ typedef
|
||||
|
||||
CLASS_EVENT *event; /* 44 event description */
|
||||
|
||||
CLASS_DESC_METHOD *array_get; /* 48 quick array get method */
|
||||
CLASS_DESC_METHOD *array_put; /* 52 quick array put method */
|
||||
int _reserved2; /* 48 quick array get method */
|
||||
int _reserved3; /* 52 quick array put method */
|
||||
|
||||
int (*check)(); /* 56 method for checking that an object is valid */
|
||||
|
||||
@ -304,6 +304,14 @@ typedef
|
||||
}
|
||||
CLASS_SPECIAL;
|
||||
|
||||
typedef
|
||||
enum {
|
||||
CQA_NONE = 0,
|
||||
CQA_ARRAY = 1,
|
||||
CQA_COLLECTION = 2
|
||||
}
|
||||
CLASS_QUICK_ARRAY;
|
||||
|
||||
typedef
|
||||
enum
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ typedef
|
||||
struct {
|
||||
GB_DESC *desc;
|
||||
CLASS **class;
|
||||
bool array;
|
||||
int array;
|
||||
}
|
||||
CLASS_INIT;
|
||||
|
||||
@ -97,7 +97,7 @@ static CLASS_INIT init_list[] =
|
||||
{ NATIVE_Component, NULL },
|
||||
{ NATIVE_Components, NULL },
|
||||
{ NATIVE_Object, NULL },
|
||||
{ NATIVE_Collection, &CLASS_Collection },
|
||||
{ NATIVE_Collection, &CLASS_Collection, CQA_COLLECTION },
|
||||
// { NATIVE_List, NULL },
|
||||
{ NATIVE_Error, NULL },
|
||||
{ NATIVE_Stream, &CLASS_Stream },
|
||||
@ -118,18 +118,18 @@ static CLASS_INIT init_list[] =
|
||||
|
||||
{ NATIVE_ArrayBounds, NULL },
|
||||
{ NATIVE_Array, &CLASS_Array },
|
||||
{ NATIVE_BooleanArray, &CLASS_BooleanArray, TRUE },
|
||||
{ NATIVE_ByteArray, &CLASS_ByteArray, TRUE },
|
||||
{ NATIVE_ShortArray, &CLASS_ShortArray, TRUE },
|
||||
{ NATIVE_IntegerArray, &CLASS_IntegerArray, TRUE },
|
||||
{ NATIVE_FloatArray, &CLASS_FloatArray, TRUE },
|
||||
{ NATIVE_SingleArray, &CLASS_SingleArray, TRUE },
|
||||
{ NATIVE_DateArray, &CLASS_DateArray, TRUE },
|
||||
{ NATIVE_StringArray, &CLASS_StringArray, TRUE },
|
||||
{ NATIVE_ObjectArray, &CLASS_ObjectArray, TRUE },
|
||||
{ NATIVE_VariantArray, &CLASS_VariantArray, TRUE },
|
||||
{ NATIVE_LongArray, &CLASS_LongArray, TRUE },
|
||||
{ NATIVE_PointerArray, &CLASS_PointerArray, TRUE },
|
||||
{ NATIVE_BooleanArray, &CLASS_BooleanArray, CQA_ARRAY },
|
||||
{ NATIVE_ByteArray, &CLASS_ByteArray, CQA_ARRAY },
|
||||
{ NATIVE_ShortArray, &CLASS_ShortArray, CQA_ARRAY },
|
||||
{ NATIVE_IntegerArray, &CLASS_IntegerArray, CQA_ARRAY },
|
||||
{ NATIVE_FloatArray, &CLASS_FloatArray, CQA_ARRAY },
|
||||
{ NATIVE_SingleArray, &CLASS_SingleArray, CQA_ARRAY },
|
||||
{ NATIVE_DateArray, &CLASS_DateArray, CQA_ARRAY },
|
||||
{ NATIVE_StringArray, &CLASS_StringArray, CQA_ARRAY },
|
||||
{ NATIVE_ObjectArray, &CLASS_ObjectArray, CQA_ARRAY },
|
||||
{ NATIVE_VariantArray, &CLASS_VariantArray, CQA_ARRAY },
|
||||
{ NATIVE_LongArray, &CLASS_LongArray, CQA_ARRAY },
|
||||
{ NATIVE_PointerArray, &CLASS_PointerArray, CQA_ARRAY },
|
||||
|
||||
{ NATIVE_SubCollection, &CLASS_SubCollection },
|
||||
|
||||
@ -141,7 +141,6 @@ void CLASS_init_native(void)
|
||||
{
|
||||
CLASS_INIT *init;
|
||||
CLASS *class;
|
||||
CLASS_DESC_METHOD *cdm;
|
||||
|
||||
/* NOTE: The 'Class' class must be first in the global class table */
|
||||
CLASS_Class = CLASS_find("Class");
|
||||
@ -155,11 +154,7 @@ void CLASS_init_native(void)
|
||||
class = CLASS_register(init->desc);
|
||||
if (init->class != NULL)
|
||||
*init->class = class;
|
||||
if (init->array)
|
||||
{
|
||||
class->array_get = (CLASS_DESC_METHOD *)CLASS_get_desc(class, class->special[SPEC_GET]);
|
||||
class->array_put = (CLASS_DESC_METHOD *)CLASS_get_desc(class, class->special[SPEC_PUT]);
|
||||
}
|
||||
class->quick_array = init->array;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "gbx_array.h"
|
||||
#include "gbx_c_array.h"
|
||||
#include "gbx_c_collection.h"
|
||||
#include "gbx_api.h"
|
||||
|
||||
|
||||
void EXEC_pop_unknown(void)
|
||||
@ -248,7 +249,7 @@ void EXEC_pop_array(ushort code)
|
||||
ARRAY_DESC *desc;
|
||||
|
||||
val = &SP[-np];
|
||||
goto *jump[(code & 0xC0) >> 6];
|
||||
goto *jump[(code >> 6) & 3];
|
||||
|
||||
__POP_GENERIC:
|
||||
|
||||
@ -260,10 +261,10 @@ __POP_GENERIC:
|
||||
|
||||
EXEC_object(val, &class, &object, &defined);
|
||||
|
||||
if (defined && class->array_put)
|
||||
if (defined && class->quick_array)
|
||||
{
|
||||
*PC |= 2 << 6;
|
||||
goto __POP_QUICK_ARRAY_2;
|
||||
goto __POP_ARRAY_2; // Check number of arguments by not going to __POP_QUICK_ARRAY immediately
|
||||
}
|
||||
|
||||
*PC |= 3 << 6;
|
||||
@ -293,24 +294,38 @@ __POP_QUICK_ARRAY:
|
||||
|
||||
EXEC_object(val, &class, &object, &defined);
|
||||
|
||||
__POP_QUICK_ARRAY_2:
|
||||
if (class->quick_array == CQA_ARRAY)
|
||||
{
|
||||
TYPE type = ((CARRAY *)object)->type;
|
||||
|
||||
swap = val[0];
|
||||
val[0] = val[-1];
|
||||
val[-1] = swap;
|
||||
|
||||
VALUE_conv(&val[0], type);
|
||||
for (i = 1; i < np; i++)
|
||||
VALUE_conv(&val[i], T_INTEGER);
|
||||
|
||||
data = CARRAY_get_data_multi((CARRAY *)object, (GB_INTEGER *)&val[1], np - 1);
|
||||
if (!data)
|
||||
PROPAGATE();
|
||||
VALUE_write(val, data, type);
|
||||
|
||||
SP = val + 1;
|
||||
RELEASE_MANY(SP, 2);
|
||||
//OBJECT_UNREF(&object, "EXEC_push_array");
|
||||
}
|
||||
else // CQA_COLLECTION
|
||||
{
|
||||
VALUE_conv(&val[-1], T_VARIANT);
|
||||
VALUE_conv(&val[1], T_STRING);
|
||||
|
||||
if (GB_CollectionSet((GB_COLLECTION)object, val[1]._string.addr + val[1]._string.start, val[1]._string.len, (GB_VARIANT *)&val[-1]))
|
||||
PROPAGATE();
|
||||
|
||||
RELEASE_MANY(SP, 3);
|
||||
}
|
||||
|
||||
swap = val[0];
|
||||
val[0] = val[-1];
|
||||
val[-1] = swap;
|
||||
|
||||
VALUE_conv(&val[0], ((CARRAY *)object)->type);
|
||||
for (i = 1; i < np; i++)
|
||||
VALUE_conv(&val[i], T_INTEGER);
|
||||
|
||||
EXEC.nparvar = np - 2;
|
||||
if (EXEC_call_native(class->array_put->exec, object, class->array_put->type, val))
|
||||
PROPAGATE();
|
||||
|
||||
SP = val + 1;
|
||||
POP();
|
||||
POP();
|
||||
//OBJECT_UNREF(&object, "EXEC_push_array");
|
||||
return;
|
||||
|
||||
__POP_ARRAY:
|
||||
@ -319,21 +334,14 @@ __POP_ARRAY:
|
||||
|
||||
__POP_ARRAY_2:
|
||||
|
||||
/* remplace l'objet par la valeur <20>ins<6E>er */
|
||||
/* swap object and value to be inserted */
|
||||
|
||||
swap = val[0];
|
||||
val[0] = val[-1];
|
||||
val[-1] = swap;
|
||||
|
||||
/*printf("<< EXEC_pop_array: np = %d SP = %d\n", np, SP - (VALUE *)STACK_base);
|
||||
save_SP = SP - np;*/
|
||||
|
||||
if (EXEC_special(SPEC_PUT, class, object, np, TRUE))
|
||||
THROW(E_NARRAY, class->name);
|
||||
|
||||
/*printf(">> EXEC_pop_array: SP = %d\n", SP - (VALUE *)STACK_base);
|
||||
if (SP != save_SP)
|
||||
printf("**** SP should be %d\n", save_SP - (VALUE *)STACK_base);*/
|
||||
|
||||
POP(); /* on lib<69>e l'objet */
|
||||
POP(); /* free the object */
|
||||
}
|
||||
|
@ -32,8 +32,9 @@
|
||||
|
||||
#include "gbx_string.h"
|
||||
#include "gbx_array.h"
|
||||
#include "gbx_c_array.h"
|
||||
#include "gbx_c_collection.h"
|
||||
|
||||
#include "gbx_api.h"
|
||||
|
||||
void EXEC_push_unknown(ushort code)
|
||||
{
|
||||
@ -435,7 +436,7 @@ void EXEC_push_array(ushort code)
|
||||
val = &SP[-np];
|
||||
np--;
|
||||
|
||||
goto *jump[(code & 0xC0) >> 6];
|
||||
goto *jump[(code >> 6) & 3];
|
||||
|
||||
__PUSH_GENERIC:
|
||||
|
||||
@ -447,10 +448,10 @@ __PUSH_GENERIC:
|
||||
|
||||
EXEC_object(val, &class, &object, &defined);
|
||||
|
||||
if (defined && class->array_get)
|
||||
if (defined && class->quick_array)
|
||||
{
|
||||
*PC |= 2 << 6;
|
||||
goto __PUSH_ARRAY_2;
|
||||
goto __PUSH_ARRAY_2; // Check number of arguments by not going to __PUSH_QUICK_ARRAY immediately
|
||||
}
|
||||
|
||||
*PC |= 3 << 6;
|
||||
@ -477,19 +478,36 @@ __PUSH_STATIC_ARRAY:
|
||||
__PUSH_QUICK_ARRAY:
|
||||
|
||||
EXEC_object(val, &class, &object, &defined);
|
||||
|
||||
__PUSH_QUICK_ARRAY_2:
|
||||
|
||||
for (i = 1; i <= np; i++)
|
||||
VALUE_conv(&val[i], T_INTEGER);
|
||||
|
||||
EXEC.nparvar = np - 1;
|
||||
if (EXEC_call_native(class->array_get->exec, object, class->array_get->type, &val[1]))
|
||||
PROPAGATE();
|
||||
if (class->quick_array == CQA_ARRAY)
|
||||
{
|
||||
for (i = 1; i <= np; i++)
|
||||
VALUE_conv(&val[i], T_INTEGER);
|
||||
|
||||
data = CARRAY_get_data_multi((CARRAY *)object, (GB_INTEGER *)&val[1], np);
|
||||
if (!data)
|
||||
PROPAGATE();
|
||||
VALUE_read(val, data, ((CARRAY *)object)->type);
|
||||
SP = val;
|
||||
PUSH();
|
||||
}
|
||||
else /* CQA_COLLECTION */
|
||||
{
|
||||
VALUE_conv(&val[1], T_STRING);
|
||||
GB_CollectionGet((GB_COLLECTION)object, val[1]._string.addr + val[1]._string.start, val[1]._string.len, (GB_VARIANT *)val);
|
||||
|
||||
RELEASE(&val[1]);
|
||||
SP = val;
|
||||
PUSH();
|
||||
}
|
||||
|
||||
//EXEC.nparvar = np - 1;
|
||||
//if (EXEC_call_native(class->array_get->exec, object, class->array_get->type, &val[1]))
|
||||
// PROPAGATE();
|
||||
//SP = val;
|
||||
//COPY_VALUE(SP, &TEMP);
|
||||
//PUSH();
|
||||
|
||||
SP = val;
|
||||
COPY_VALUE(SP, &TEMP);
|
||||
PUSH();
|
||||
OBJECT_UNREF(&object, "EXEC_push_array");
|
||||
return;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user