Rmagick, GraphicsMagick seems to be super slow on server (why OK on local)
-
08-03-2021 - |
Question
I am looking for a very quick way to render dynamic images from small tiles placed on some background (imagine dynamically rendering a chess game and sending images after each player makes a move). So the procedure seems to be quite simple: 1. Take some background 2. Put transparent images of chess figures from top to bottom using image offsets (to have correct perspective) 3. Save the whole picture as gif
Tried using imagemagick:
using something similar to:
convert -page 176x220 -gravity SouthWest 1.png -page +35+30 -gravity SouthWest 1.png -page +62+50 1.png -page +10+55 1.png -background none -compose DstOver -flatten result.gif
And graphics magick in similar way: gm convert ... -page+35+-30 -flatten..
But was not impressed, GraphicsMagick provided better results but:
SERVER:
user system total real
all: 0.000000 0.000000 47.650000 ( 70.991829)
small: 0.000000 0.000000 6.600000 ( 8.110900)
medium: 0.000000 0.000000 6.820000 ( 8.494131)
large: 0.000000 0.000000 10.890000 ( 15.818351)
extreme: 0.000000 0.000000 11.160000 ( 19.873541)
biggest: 0.000000 0.000000 11.640000 ( 14.327450)
On local Phenom II x6:
user system total real
all: 0.000000 0.000000 1.980000 ( 0.757320)
small: 0.000000 0.000000 0.330000 ( 0.082142)
medium: 0.000000 0.000000 0.380000 ( 0.127744)
large: 0.000000 0.000000 0.410000 ( 0.147252)
extreme: 0.000000 0.000000 0.440000 ( 0.180338)
biggest: 0.000000 0.000000 0.470000 ( 0.210802)
Thought maybe the file loading is the issue, tried Rmagick(script from: http://www.imagemagick.org/RMagick/doc/ilist.html#mosaic ):
require "benchmark"
require 'RMagick'
#Demonstrate the mosaic method
a = Magick::ImageList.new
26.times do
a.read("csii/some_asset.miff")
end
b = Magick::ImageList.new
page = Magick::Rectangle.new(0,0,0,0)
a.scene = 0
2.times do |i|
2.times do |j|
b << a.scale(1)
page.x = j * b.columns
page.y = i * b.rows
b.page = page
(a.scene += 1) rescue a.scene = 0
end
end
# Make a 5x5 mosaic
#mosaic = b.flatten_images
#mosaic.write("mosaic.gif")
# mosaic.display
Benchmark.bm(7) do |ben|
ben.report("tiny:") {mosaic = b.mosaic}
end
exit
The result is even more wierd: THIS IS FOR A TINY 2*2 tiles image
SERVER:
user system total real
tiny: 16.210000 0.000000 16.210000 ( 16.982007)
PHENOM:
user system total real
tiny: 0.000000 0.010000 0.010000 ( 0.001637)
ADDITIONAL INFO:
INPUT FILE FORMATS: tried png and miff
OUTPUT: must be gif
SERVER: 1 XEON core on VPS ~2.2Ghz
PHENOM: 6* 3.2Ghz
Version differences:
Phenom
Version: ImageMagick 6.5.7-8 2010-12-02 Q16 http://www.imagemagick.org
Server
Version: ImageMagick 6.5.1-0 2010-12-02 Q16 OpenMP http://www.imagemagick.org
QUESTIONS
- Any ideas for the up to 10000 times reduction in speed?
- Any ideas of how I could achieve this task in any other way(other GM or IM function?) or method (Trying out chunky_PNG now (with oily_png ext.)?
- The old 2d games of DOS era could render even more pixels at 60fps, so I guess it should be able to accomplish this on a 2Ghz CPU (200ms would be OK I guess)?
Solution
It seems every time I ask a question on SO, the answer comes to me immediately.
This time it seems the performance issue is because of OpenVz VPS and OpenMP in IM and GM. After recompiling without OpenMP feature, the performance is great on the server.
OTHER TIPS
RMagick is known to cause all sorts of issues in production (mostly related to memory leaks). I don't know the details, but I do know that using mini_magick alleviates most performance problems. Maybe you should give it a shot.