4

Is it possible to somehow inline a function in python?

I have a very long function in python, which I want to split up for readability in several functions. So the parts gets called only from one point, the in program, but very often.

This reduces performance since function calls are very expensive.

Is there a method to both maintain the unsplitted performance, while improving readability/maintainence?

user3666197
  • 1
  • 6
  • 50
  • 92
appppple
  • 71
  • 1
  • 5
  • 2
    "...function calls are very expensive." Have you measured this, that is, compared the long function and the one split in multiple parts? – Wander Nauta Jan 04 '16 at 16:39
  • Yes i profiled it and there is definitely a not so small slow down. The long function gets called very very often. – appppple Jan 04 '16 at 16:50
  • 1
    If you are so worried about performance, then consider using a compiled language like Cython or C for the most critical parts. – Andrea Corbellini Jan 04 '16 at 16:52
  • Could you be quantitative and state profiling overhead times? – user3666197 Jan 04 '16 at 16:52
  • 1
    If the time spent calling a function is a bottleneck, Python is not the right language for your use case. – Vincent Savard Jan 04 '16 at 16:56
  • 1
    I guess your question is too vague. Give us some more information such as performance gains and code – rafaelc Jan 04 '16 at 16:57
  • FWIW, when comparing performance you should look at percentages, not at absolute numbers (i.e. "50% slowdown" means something, "2 usec slowdown" doesn't mean anything). This might sound obvious, but it is a frequent mistake – Andrea Corbellini Jan 04 '16 at 16:59
  • Oh, and other than Cython there's also PyPy: 100% Python compatible, but with a just in time compiler. – Andrea Corbellini Jan 04 '16 at 17:00

3 Answers3

4

There are several ways to inline in Python

Besides numba and similar JIT compilers ( which retain their own inline caches ), that may help you in JIT-code-reuse, as you denoted in numerous re-call of the unspecified function, there are several ways how to inline into Python code.


Inline symbolic x86 ASM assembly language into python

from pyasm              import Program
from pyasm.data         import String
from pyasm.macro        import syscall
from pyasm.instructions import mov, ret, push, add
from pyasm.registers    import eax, ebx, ecx, edx, ebp
import sys

def example():
    msg = 'Hello World!'
    prog = Program(     # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
                        #
                        ### ASSUME NOTHING - a lovely ASM note to always remember & self.remind
                        mov(ebx, 1),
                        mov(ecx, String(msg)),
                        mov(edx, len(msg)),
                        syscall('write'),
                        ret(),
                        # _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
                        )
    fun = prog.compile()
    fun()

if __name__ == '__main__':
    example()

Inline almost c language into python

from pycca.cc import CCode, Function, Assign, Return

code = CCode( [ Function( 'int', 'add_one', [( 'int', 'x' )],
                        [
                          Assign( x='x + 1' ),
                          Return('x')
                          ])
                ])
print code.dump_asm()
print "3 + 1 = %d" % code.add_one( 3 )

For details & other options look at >>> this


Inline c language into python ( since 2001 )

import PyInline, __main__

m = PyInline.build( language     = "C",
                    targetmodule = __main__,
                    code         = """
                                   /*_______________________________WORLDS-OF-C*/


                                     double my_C_adder( double a, double b )
                                     {
                                                        return a + b;
                                     }


                                   /*_______________________________WORLDS-OF-C*/
                                  """
                    )

print my_C_adder( 4.5, 5.5 )                     # Should print out "10.0"

Another approach at >>> PyInline

Community
  • 1
  • 1
user3666197
  • 1
  • 6
  • 50
  • 92
2

CPython interpreter does not support function inlining.

For performance-critical sections you may consider writing C-extension or using C Foreign Function Interface library.

C Foreign Function Interface for Python. The goal is to provide a convenient and reliable way to call compiled C code from Python using interface declarations written in C.

Another alternative is PyPy interpreter, which is equipped with JIT compiler and tends to achieve huge performance gains.

It depends greatly on the type of task being performed. The geometric average of all benchmarks is 0.14 or 7.0 times faster than CPython

Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
1

No, Python doesn't support inline functions.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • 1
    Mark, you might want to know that your text does not prove to be correct & you might want to update or remove the original statement. **Anyway, PF-2016** – user3666197 Jan 06 '16 at 04:05
  • @user3666197 Python doesn't support it in the OP's definition, writing multiple Python functions but inlining them to have the same performance as a single function. It isn't in the language definition. Sure you can write an extension in *another* language that improves performance. C++ has inlining; Python does not. – Mark Tolonen Jan 06 '16 at 04:49
  • 1
    With all due respect, Mark, the **`numba`** use-case does hold both the OP's definition & OP's motivation (performance+maintainability+(cit.)"... very, very often" call/code re-use) while at the same time does provide purely pythonesque solution [*I would dare to accuse Travis for "not keeping (also OP's) python ideals"*]. Yes, there are limitation of what can be numba-accelerated, but that is why there are other approaches (just let's take the genuine **`PyInline`** worlds-of-c) mentioned. Yes, Guido had initially another mindset, but check Mitchell Charity's note in PyInline ref'd below. – user3666197 Jan 06 '16 at 06:26
  • @user366197, Your definition of inlining differs from mine. Does Python have a language function similar to C++'s inline keyword? No. Can you write extensions that accelerate performance? Yes. – Mark Tolonen Jan 06 '16 at 06:37
  • 2
    In a serious context, Stroustrup himself in [The design and evolution of C++] refers to `inline` as being a 'hint' to the compiler. It allows to define the same function in more than one translation unit. This is a prerequisite for inlining the function at a call-spot (**without link-time optimization**), which is where the **keyword** got it's name. IMHO, OP is not related to keyword(s), nor to c/C++ language per se, nor to compile-/link-time code-optimisation, **but to root idea** of inline-d pieces of code ( i.e. **why to design a code in this particular way**, independently of keywords ) – user3666197 Jan 06 '16 at 06:55