1

I need to be able to call Python functions from Java, and get the return of those functions, which should be primitives only.
I also don't need to access Java objects in Python or other stuff like that.
But, most of all, I need speed. I need to be able to load the script at the start of my application and then call some functions at different time-intervals, which can sometimes get really tiny (30-40 times per second).
That's the main-reason why I don't think that Jython will work for me: It has all kinds of stuff that I don't need, and is incredibly slow.

So, those are the constraints/requirements I have:

  • Needs to be fast
  • I need to call python functions and get their result
  • The script should be loaded only once

Do you guys know about another way to simply call Python functions in a pre-loaded script (So that the script does not have to be loaded again and again for each function call)?

(PS: I do not think that this is a duplicate as I searched quite a lot and all links I found did not answer my question (For example Calling Python in Java?) )

Community
  • 1
  • 1
Fly
  • 810
  • 2
  • 9
  • 28
  • Make a ReST call to a python service? – Elliott Frisch Oct 22 '15 at 12:54
  • @ElliottFrisch Uh, what exactly do you mean? Let the Python scripts run as some kinds of services? The question would still be how do I actually access the function from Java, etc. And if you mean an online service, that wont work at all. I need the fastest way possible and thats probably the slowest. – Fly Oct 22 '15 at 12:58
  • I take your point, [thrift](http://thrift.apache.org/) is so slow that facebook is built on it. I'm confident your solution will scale better than that. – Elliott Frisch Oct 22 '15 at 13:08
  • @ElliottFrisch Didn't know that. Also I thought you meant a "real" "online" service, which would be way too slow (Anything that requires internet access won't work for me as the application will need to work on offline machines.) - But you mean something like emulating a network on the machine itself, right? Sorry if I sound too stupid – Fly Oct 22 '15 at 13:14
  • Local sockets are pretty fast. A local cluster can handle scaling. The real question is what you want to optimize for (throughput or concurrency). Either way, using an [n-tier design](https://en.wikipedia.org/wiki/Multitier_architecture) would be my strategy. – Elliott Frisch Oct 22 '15 at 13:16
  • @ElliottFrisch Problem is that everything can vary as I won't write the scripts myself: Some of them could return huge objects (Even if they're just primitives). I think that I won't need "high" concurrency though, as most of the scripts that will finally be run aren't important and can therefore be run after the important ones. Also, I don't know about the n-tier design: The logic-part is distributed amongst the scripts and my application, which in turn is distributed amongst multiple local machines. (It is also the first time I'm doing something like this so I've no clue if this sounds OK) – Fly Oct 22 '15 at 13:28

1 Answers1

1

You could write some JNI code to embed the CPython interpreter.

You could write a Python program that will run as a daemon (or web service or whatever) and connect to it via some sort of networking. I am intentionally vague here since it is such a broad question with any number of possibilities.

I don't know that either of the above will actually be faster than calling in to Jython. Note that you can load the Jython interpreter once and (re)use it for each function call.

What if you rewrote your Python function in Java? You can even load it dynamically, if that is the reason you are trying to combine multiple languages. Alternatively, Java8 comes with a (new) JavaScript engine. You could use JavaScript instead of Python.

dsh
  • 12,037
  • 3
  • 33
  • 51
  • Thanks for the answer. I guess I will have to implement each of these methods and do some benchmarking... Rewriting the function in Java isn't an option, as I am not the author of those functions, and the people programming them are no programmers: I figured Python as the way to go because it is easy to learn and has a lot of modules. (My application basically is some huge backbone for a few scripts) – Fly Oct 22 '15 at 13:01
  • @GandalfSchmidt then why don't you write the backbone in Python? Why add an extra layer of complexity by trying to jam two languages together? – jonrsharpe Oct 22 '15 at 13:04
  • @jonrsharpe Well, Python is more of a scripting language and there is some complexity involved in the application that I really don't want to write in Python. I also think that Python is too slow to run the whole application (The Java application is only a prototype since it is faster to write than in C++ - But once I got it working I will port it to C++) – Fly Oct 22 '15 at 13:10
  • @GandalfSchmidt you're just a glutton for punishment, huh? If you want a language that's fast to write a prototype in, why on earth choose Java?! Or just go straight to C++, which is easier to interoperate with Python than Java is. – jonrsharpe Oct 22 '15 at 13:11
  • @jonrsharpe Uh, well, personally I find Java easier to write a prototype in than C++, and I used to use Java a lot back then so I thought it would be a good choice. Also I know (and used before) some library in Java that handles a huge part of work for me which I would be obligated to write myself in C++, thats why I wanted it to be written in java first. But I guess you're right, I should directly use C++.. – Fly Oct 22 '15 at 13:18
  • @GandalfSchmidt I agree with jonrsharpe: write your prototype in Python. Then it is easy to call the functions. Then port it to C++ using the API for embedding the CPython interpreter. Writing JNI to embed it in Java will cost you more for no benefit when you rewrite the whole deal in C++. – dsh Oct 22 '15 at 15:25
  • @GandalfSchmidt can you share your results of your benchmarking? – dbustosp Aug 17 '17 at 22:12