GT.M binding to Python and C++ Profiling

Following up on the recent posts on GT.M bindings for other languages:

 

 

It is natural to ask about the computational performance of these bindings.

To attempt to answer this question, we prepared the following three basic tests:

 

 

They are implementations of a basic computation of first 100 terms
of the Fibonacci series, repeated 1000 times.

 

The measurements of running these tests in a DELL PRECISION M6700 were:

 

  • M         = 0.37 seconds
  • C++     = 1.10 seconds
  • Python = 1.75 seconds

 

This is consistent with what one can expect, knowing that the C++ implementation is
going through the C API of GT.M, and that the Python implementation is produced by
wrapping the C++ implementation using SWIG.

 

Please share your comments and ideas on how to improve and better take advantage
of these bindings.

 

 

like0

Comments

Thoughts

Robert Sax's picture

I would generally guess that you would not execute Mumps in the way you have shown. I would suspect that you would normally call a M routine that did the work and just get the result instead of essentially writing the M program in the calling language.

That being said, the performance hit seems significant for C++. Perhaps you can condense the M code to one or two lines so that the interpreter works better?

As a side note, I translated the mumps code you wrote to java and ran it on a 2.5Ghz i7 macbook pro (somewhat less powerful than your system). The result was .002 seconds (185x faster), showing that Mumps or perhaps GTM performance is decimated by its interpreter.

 

Rob

 

like0

GT.M binding to Python and C++ Profiling

Sam Habiel's picture

Rob,

Does your Java code save each calculation to a database? That's what the
Mumps code does.

Sam

like0

database

Robert Sax's picture

Fair enough - missed that globals were being written (and I will agree that makes a significant difference in perfomance).  Was there a reason for using a global?  Does it affect the speed of the interface from C++ or Python?

Rob

like0

GT.M binding to Python and C++ Profiling

Sam Habiel's picture

It's just a simple program that does what Mumps idiomatically does (if it didn't write to globals, it's pretty useless as a language!) I only saw the python program, but yes, it writes to globals too.

Sam

like0

Scenario exercising access to database

Luis Ibanez's picture

Rob,

The purpose of the test was to evaluate the difference in performance bewteen accessing the M database from the M language, versus, accessing it through the C API via the Python and C++ wrappings.

That's the reason why globals are being accessed in this test code.

Our interest in this case was in exercising the use of the database (hence the globals).

Normally, one wouldn't be interested in using a Python or C++ in order to use M-language local variables. On the contrary, globals (database entries) is what we most likely would like to access from other languages.

Your point is well taken regarding the fact that this is not how one would usually program an application for deployment in production. This is only giving us a sense of the overhead involved in accessing the M database from a different language.

The final goal is to bring the M database to be accessible from many languages, just like you can do today with MySQL, MongoDB, or Redis, for example.

At this point we have covered C++, Python, Node.js, and we are working towards Ruby, R and Java.

like0

Scenario

Robert Sax's picture

Thanks for the explanation - it helps alot. So given this scenario, I have a couple of comments on the way the code is put together. 

Is there any way to hit the M database without writing M code that must then be interpreted? IE if you are hitting it from C/C++ and it (GT.M) is written in C/C++ - wouldn't there be a lower level entry point that allows you to perform the CRUD directly?  It would seem to me that would perform significantly better.

So I assume from what you write that you are really looking at a sort of database driver. For this type of solution, I would expect the approach would be a daemon that sits on the VistA machine, and then other languages accessing the daemon from a remote machine. The daemon itself would be need to be C++ (or even hand-tuned assembly) for best performance. If a test case was set up in this way, the speed of the interface would probably be dictated by how fine-grained the interface was - ie simple set/get would cause significant network overhead. Are there any "object" centric approaches to set/get in the GT.M interface? If there is the ability to set an entire hierarchy, perhaps that would be a good thing to work into this scenario?

Your test case is write-centric - approximately 75% write, 25% read. In most real-world applications it should be more like 90% read, 10% write. I'm not sure that has any bearing on this type of test case though. The delta between the C++ and Python numbers appear to be testing the speed of SWIG more than testing the speed (or special capabilities, or paradigms) of Python. I would guess that the other languages that you have lined up will have similar overhead.

Rob

like0