improve f-string performance

This commit is contained in:
blueloveTH 2023-12-08 22:29:22 +08:00
parent b8100bcce5
commit 9af3434f06
6 changed files with 19 additions and 7 deletions

View File

@ -90,7 +90,7 @@ OPCODE(LOOP_CONTINUE)
OPCODE(LOOP_BREAK) OPCODE(LOOP_BREAK)
OPCODE(GOTO) OPCODE(GOTO)
/**************************/ /**************************/
OPCODE(EVAL_CONST) OPCODE(FSTRING_EVAL)
OPCODE(REPR) OPCODE(REPR)
OPCODE(CALL) OPCODE(CALL)
OPCODE(CALL_TP) OPCODE(CALL_TP)

View File

@ -225,7 +225,6 @@ const StrName __class__ = StrName::get("__class__");
const StrName pk_id_add = StrName::get("add"); const StrName pk_id_add = StrName::get("add");
const StrName pk_id_set = StrName::get("set"); const StrName pk_id_set = StrName::get("set");
const StrName pk_id_eval = StrName::get("eval");
#define DEF_SNAME(name) const static StrName name(#name) #define DEF_SNAME(name) const static StrName name(#name)

View File

@ -136,6 +136,9 @@ public:
PyObject* _last_exception; // last exception PyObject* _last_exception; // last exception
PyObject* _curr_class; // current class being defined PyObject* _curr_class; // current class being defined
// cached code objects for FSTRING_EVAL
std::map<std::string_view, CodeObject_> _cached_codes;
#if PK_ENABLE_CEVAL_CALLBACK #if PK_ENABLE_CEVAL_CALLBACK
void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr; void (*_ceval_on_step)(VM*, Frame*, Bytecode bc) = nullptr;
#endif #endif

View File

@ -568,10 +568,19 @@ __NEXT_STEP:;
frame->jump_abs_break(index); frame->jump_abs_break(index);
} DISPATCH(); } DISPATCH();
/*****************************************/ /*****************************************/
TARGET(EVAL_CONST){ TARGET(FSTRING_EVAL){
PyObject* _0 = builtins->attr(pk_id_eval); PyObject* _0 = co_consts[byte.arg];
PyObject* _1 = co_consts[byte.arg]; std::string_view string = CAST(Str&, _0).sv();
PUSH(call(_0, _1)); auto it = _cached_codes.find(string);
CodeObject_ code;
if(it == _cached_codes.end()){
code = vm->compile(string, "<eval>", EVAL_MODE, true);
_cached_codes[string] = code;
}else{
code = it->second;
}
_0 = vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
PUSH(_0);
} DISPATCH(); } DISPATCH();
TARGET(REPR) TARGET(REPR)
TOP() = py_repr(TOP()); TOP() = py_repr(TOP());

View File

@ -392,7 +392,7 @@ namespace pkpy{
} }
}else{ }else{
int index = ctx->add_const(py_var(ctx->vm, expr)); int index = ctx->add_const(py_var(ctx->vm, expr));
ctx->emit_(OP_EVAL_CONST, index, line); ctx->emit_(OP_FSTRING_EVAL, index, line);
} }
if(repr){ if(repr){
ctx->emit_(OP_REPR, BC_NOARG, line); ctx->emit_(OP_REPR, BC_NOARG, line);

View File

@ -1199,6 +1199,7 @@ void ManagedHeap::mark() {
if(vm->_last_exception) PK_OBJ_MARK(vm->_last_exception); if(vm->_last_exception) PK_OBJ_MARK(vm->_last_exception);
if(vm->_curr_class) PK_OBJ_MARK(vm->_curr_class); if(vm->_curr_class) PK_OBJ_MARK(vm->_curr_class);
if(vm->_c.error != nullptr) PK_OBJ_MARK(vm->_c.error); if(vm->_c.error != nullptr) PK_OBJ_MARK(vm->_c.error);
for(auto [_, co]: vm->_cached_codes) co->_gc_mark();
} }
Str obj_type_name(VM *vm, Type type){ Str obj_type_name(VM *vm, Type type){