Currently I'm using JSON as a serialization format to transfer a simple hash containing strings, numbers and an array from Ruby into a Python script:
IO.popen('./convert.py', 'w') do |w|
w.write({ :height => height, :width => width, :id => job_id, :data => pix }.to_json)
w.write "\n"
w.close_write
end
In this case height
, width
and job_id
are all numbers and pix
is an array of arrays of integers.
The python script this is running is:
#!/usr/bin/env python
from PIL import Image
import json
import sys
output = json.load(sys.stdin)
width = output['width']
height = output['height']
name = 'images/' + str(output['id']) + '/image.bmp'
data = [ tuple(datum) for datum in output['data'] ]
img = Image.new("RGB", (width, height))
img.putdata(data)
img.save(name)
A bit of quick testing utilising an array with 3.9 million values (probably around 1/4 of the size that will normally be used) revealed the script to take around 105 seconds, and 90 seconds with all lines below output = ...
commented out. Obviously it would be good if the serialisation didn't take 85% of the processing time for such a simple script.
The only method to speed this up that I can think of is to find some form of binary serialisation/marshalling that could be utilised to transfer the data from Ruby to Python. Unfortunately I have been unable to find any such system, only RMarshal which appears to be able to work the other way.
Ruby and Python are two highly sought-after programming languages. They share many similarities and both are powerful options that solve specific problems. But few people know that Ruby and Python can be brought together to create efficient apps with capabilities for heavy calculations and handling Big Data.
Python support multiple inheritance, while Ruby support single inheritance. Python is mainly used for academic, AI, machine learning, and scientific programming, while Ruby is used for web development and functional programming. Python is not a fully object-oriented programming language.
To do so, you would need to make your script into a proper Python module, start the bridge when the Rails app starts, then use RubyPython. import to get a reference to your module into your Ruby code. The examples on the gem's GitHub page are quite simple, and should be sufficient for your purpose.
Maybe MessagePack is the way to go then. Bindings for several languages exist, including Ruby and Python.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With