Issue #2889: Unnecessary tuple creation when passing string object with CFFI and jit enabled (pypy/pypy)
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-... 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) ```
participants (1)
-
Tinho Lee