New issue 2889: Unnecessary tuple creation when passing string object with CFFI
and jit enabled
https://bitbucket.org/pypy/pypy/issues/2889/unnecessary-tuple-creation-when-passing
Tinho Lee:
It seems some optimization could help to improve the performance of passing
python string to c library through cffi.
*get_nonmovingbuffer* is called when raw char pointer is needed. The annotation
*always_inline* is set in order to get rid of the returned tuple, however, this
function is decorated by *jit.dont_look_inside*, so the pypy_tuple cannot be
eliminated when jit is in operation. I have confirmed *get_nonmovingbuffer*,
instead of the inline version, is called with linux perf and jit log.
```
#!python
@jit.dont_look_inside
def get_nonmovingbuffer(data):
lldata = llstrtype(data)
count = len(data)
if rgc.must_split_gc_address_space():
flag = '\x06' # always make a copy in this case
elif we_are_translated_to_c() and not rgc.can_move(data):
flag = '\x04' # no copy needed
else:
if we_are_translated_to_c() and rgc.pin(data):
flag = '\x05' # successfully pinned
else:
flag = '\x06' # must still make a copy
if flag == '\x06':
buf = lltype.malloc(TYPEP.TO, count + (TYPEP is CCHARP),
flavor='raw')
copy_string_to_raw(lldata, buf, 0, count)
return buf, '\x06'
data_start = cast_ptr_to_adr(lldata) + \
offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
return cast(TYPEP, data_start), flag
get_nonmovingbuffer._always_inline_ = 'try' # get rid of the returned tuple
get_nonmovingbuffer._annenforceargs_ = [strtype]
```
I don't think the returned tuple is necessary in this case. Maybe something
like change the implementation into two function calls would help to remove the
memory allocation of returned value, which decreases the total gc object.
```
#!python
def get_nonmovingbuffer_flag(data)
def get_nonmovingbuffer_buf(data, flag)
```
_______________________________________________
pypy-issue mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-issue