optimize str's iterator

This commit is contained in:
blueloveTH 2023-08-22 23:55:11 +08:00
parent 19eb976bd1
commit f9c0a95237
3 changed files with 25 additions and 6 deletions

View File

@ -33,7 +33,7 @@ struct StringIter{
PY_CLASS(StringIter, builtins, "_string_iterator") PY_CLASS(StringIter, builtins, "_string_iterator")
PyObject* ref; PyObject* ref;
Str* str; Str* str;
int index; int index; // byte index
StringIter(PyObject* ref) : ref(ref), str(&PK_OBJ_GET(Str, ref)), index(0) {} StringIter(PyObject* ref) : ref(ref), str(&PK_OBJ_GET(Str, ref)), index(0) {}
@ -43,7 +43,7 @@ struct StringIter{
}; };
struct Generator{ struct Generator{
PY_CLASS(Generator, builtins, "_generator") PY_CLASS(Generator, builtins, "generator")
Frame frame; Frame frame;
int state; // 0,1,2 int state; // 0,1,2
List s_backup; List s_backup;

View File

@ -32,9 +32,11 @@ namespace pkpy{
vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; }); vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; });
vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
StringIter& self = _CAST(StringIter&, obj); StringIter& self = _CAST(StringIter&, obj);
// TODO: optimize this... operator[] is of O(n) complexity if(self.index == self.str->size) return vm->StopIteration;
if(self.index == self.str->u8_length()) return vm->StopIteration; int start = self.index;
return VAR(self.str->u8_getitem(self.index++)); int len = utf8len(self.str->data[self.index]);
self.index += len;
return VAR(self.str->substr(start, len));
}); });
} }

View File

@ -117,4 +117,21 @@ assert a.rjust(5, '0') == '00123'
assert a.ljust(5) == '123 ' assert a.ljust(5) == '123 '
assert a.ljust(5, '0') == '12300' assert a.ljust(5, '0') == '12300'
assert '\x30\x31\x32' == '012' assert '\x30\x31\x32' == '012'
a = 'abcd'
assert list(a) == ['a', 'b', 'c', 'd']
a = '测试'
assert list(a) == ['', '']
a = 'a测b试c'
assert list(a) == ['a', '', 'b', '', 'c']
a = 'a测b试'
assert list(a) == ['a', '', 'b', '']
a = '测b试c'
assert list(a) == ['', 'b', '', 'c']
a = '测b'
assert list(a) == ['', 'b']
a = 'b'
assert list(a) == ['b']
a = ''
assert list(a) == ['']