Friday, January 30, 2009

Python under Moon light

After reading this post I thought of comparing the performance of python against the lightweight scripting language Lua. So to have a fair comparison I ported the MorseCode encoder/decoder wirtten in python into a Lua script with no change to the logic or the sequence.



--morse code table
codes = {
['!'] = "-.-.--", [' '] = "|", ['"'] = ".-..-.", ['$'] = "...-..-",
['\''] = ".----.", ['&'] = ".-...", [')'] = "-.--.-", ['('] = "-.--.",
['+'] = ".-.-.", ['-'] = "-....-", [','] = "--..--", ['/'] = "-..-.",
['.'] = ".-.-.-", ['1'] = ".----", ['0'] = "-----", ['3'] = "...--",
['2'] = "..---", ['5'] = ".....", ['4'] = "....-", ['7'] = "--...",
['6'] = "-....", ['9'] = "----.", ['8'] = "---..", [';'] = "-.-.-",
[':'] = "---...", ['='] = "-...-", ['?'] = "..--..", ['A'] = ".-",
['@'] = ".--.-.", ['C'] = "-.-.", ['B'] = "-...", ['E'] = ".",
['D'] = "-..", ['G'] = "--.", ['F'] = "..-.", ['I'] = "..",
['H'] = "....", ['K'] = "-.-", ['J'] = ".---", ['M'] = "--",
['L'] = ".-..", ['O'] = "---", ['N'] = "-.", ['Q'] = "--.-",
['P'] = ".--.", ['S'] = "...", ['R'] = ".-.", ['U'] = "..-",
['T'] = "-", ['W'] = ".--", ['V'] = "...-", ['Y'] = "-.--",
['X'] = "-..-", ['Z'] = "--..", ['_'] = "..--.-"
}


binary = {['.']="10",['-']="1110",[',']="000",['|']="0000000"}


function encode(value)
--encodes the value into morse code
value = string.upper(value)
value = string.gsub(value,'%*', 'X')
value = string.gsub(value,'%^', 'XX')
local morse_value=""
local length = string.len(value)
local i = 1
while i <= length do
local chr = string.sub(value,i,i)
if chr then
morse_value = morse_value .. codes[chr] .. ","
end
i = i + 1
end
return _get_binary(morse_value)
end

function _get_binary(value)
local binary_value = ""
local length = string.len(value)
local i = 1
while i <= length do
local chr = string.sub(value,i,i)
if chr then
binary_value = binary_value .. binary[chr]
end
i = i + 1
end
return binary_value
end

function decode(morse_code_value)
-- decodes the morse bytes
decoded_value = _decode_binary(morse_code_value)
ascii_value=""
for w in string.gfind(decoded_value, "[-.|]+") do
ascii_value = ascii_value .. _get_key(w)
end
return ascii_value
end

function _get_key(value)
--returns the key for the given value
for k, v in next, codes do
if v == value then
return k
end
end
return ''
end

function _decode_binary(binary)
dah_replaced = string.gsub(binary,'1110', '-')
dit_replaced = string.gsub(dah_replaced,'10', '.')
comma_replaced = string.gsub(dit_replaced,'000', ',')
zero_replaced = string.gsub(comma_replaced,'0', '|,')
return zero_replaced
end

function print_usage()
print("Usage : "..arg[0].." [d (decode) |e (encode)] [input string]")
end


if arg[1] == nil then
print_usage()
else
if arg[1] == 'd' then
print("Decoded value : "..decode(arg[2]))
elseif arg[1] == 'e' then
if arg[2] == nil then
print_usage()
else
print("Encoded value : "..encode(arg[2]))
end
else
print("Encoded value : "..encode(arg[1]))
end
end



The Lua script was much faster than the python one. May be i have not written the python script in an optimistic way, but logic remains the same.

Aanand Natarajan@AANAND /h/MorseEnDecode/src
$ time python MorseEnDecode.py aanand
encoding
Encoded : 10111000010111000011101000010111000011101000011101010000

real 0m0.140s
user 0m0.015s
sys 0m0.015s

Aanand Natarajan@AANAND /h/MorseEnDecode/src
$ time lua MorseEnDecode.lua aanand
Encoded value : 10111000010111000011101000010111000011101000011101010000

real 0m0.031s
user 0m0.015s
sys 0m0.015s


Look at the real time which is 0.140 seconds for the Python version and 0.31 seconds for the Lua version.
This doesn't mean Python is not fast. I like Python as a language, for its features and its highly performant comparing against many other scripting languages.

No comments: