tags:

views:

256

answers:

4

Am trying to provide a response from a Managers perspective to the question: What overall performance penalty will we incur if we write the application in IronPython instead of C#?

This question is directed at those who might have already undertaken some testing, benchmarking or have completed a migration from C# to IronPython, in order to quantify the penalty.

+6  A: 

I created a C# console application (I'm not very good at C#), which basically encrypts an input file using a xor cipher.

Code below:

using System;
using System.IO;
using System.Text;
using System.Diagnostics;

namespace XorCryptor
{
    class Program
    {
        public static void Main(string[] args)
        {
            if(args.Length != 3)
            {
                Console.WriteLine("Usage: xorcryptor password file_in.txt file_out.txt");
                Console.Write("Press any key to continue...");
                Console.ReadKey(true);
                return;
            }
            Stopwatch sw = Stopwatch.StartNew();
            BinaryReader infileb;
            try{
                infileb = new BinaryReader(File.Open(args[1], FileMode.Open));
            }catch(IOException){
                Console.WriteLine("Error reading from input file (is it in use by another program?)");
                return;
            }
            byte[] encb = Crypt(infileb.ReadBytes((int)infileb.BaseStream.Length),args[0]);
            infileb.Close();
            BinaryWriter outfileb;
            try{
                outfileb = new BinaryWriter(File.Open(args[2], FileMode.Create));
            }catch(IOException){
                Console.WriteLine("Error writing to output file (is it in use by another program?)");
                return;
            }
            outfileb.Write(encb);
            outfileb.Close();
            sw.Stop();
            Console.WriteLine("Size: "+encb.Length.ToString());
            Console.WriteLine("Elapsed milliseconds: "+sw.ElapsedMilliseconds.ToString());
        }
        internal static byte[] Crypt(byte[] text, string password)
        {
            int i2 = 0;
            byte[] result = new byte[text.Length];
            foreach(byte b in text)
            {
                result[i2] = Convert.ToByte(b ^ password[i2 % password.Length]);
                i2++;
            }
            return result;
        }
    }
}

and then the equivalent Python version, (I used SharpDevelop 4.0 to build an executable):

import System
from System.IO import File, FileMode, BinaryReader, BinaryWriter
from System.Diagnostics import Stopwatch
import sys

def crypt(text, password):
    result = System.Array.CreateInstance(System.Byte, text.Length)
    for i, b in enumerate(text):
        result[i] = System.Convert.ToByte(b ^ ord(password[i % len(password)]))
    return result

argv = System.Environment.GetCommandLineArgs()

if len(argv) != 4:
    print "Usage: pyxorcryptor password file_in file_out"
    print "Press any key to exit...",
    System.Console.ReadKey(True)
    sys.exit(1)

sw = Stopwatch.StartNew()
try:
    infileb = BinaryReader(File.Open(argv[2], FileMode.Open))
    outfileb = BinaryWriter(File.Open(argv[3], FileMode.Create))
except IOException, e:
    print e.ToString()
    sys.exit(1)
encb = crypt(infileb.ReadBytes(int(infileb.BaseStream.Length)), argv[1])
infileb.Close()
outfileb.Write(encb)
outfileb.Close()
sw.Stop()

print "Size: {0}\nTime (ms): {1}".format(len(encb), sw.ElapsedMilliseconds)

Testing their speeds with the same plaintext 3,827 kb file, I get this:


C#:

  • Size: 3928779
  • Elapsed milliseconds: 73

IronPython 2.6 for .NET 4.0

  • Size: 3928779
  • Time (ms): 16825

So I think we can conclude that IronPython is significantly slower than C#, in this particular scenario.

I might have made a mistake somewhere in my code in those two files, so feel free to point them out. I'm still learning.

jcao219
Many thanks for taking the time to do this. I suspect your numbers point to a considerable penalty in start up time.
Alex
Actually not,the stopwatch doesn't start ticking until after the program starts up.CPython's speed is even a bit slower than IronPython's in this task.
jcao219
Thanks for pointing that out, I didn't see that timing commenced after the application had started. Again, thanks for quantifying a particular scenario that contrasts IronPython and C#.
Alex
Correction to my comment above, I just tested and CPython is actually faster.
jcao219
I wonder if the `enumerate` is responsible for much of the difference. It creates 4M tuple objects that the C# version doesn't. That shouldn't make a difference of 16 seconds, but it is probably the biggest difference.
Gabe
I took out the enumerate and made it more close to the C# version, and the time went down to 13634 milliseconds.Perhaps there are other optimizations possible.
jcao219
It's also possible that the `.Length` call gets optimized away so it only happens once, while the `len()` call happens 4M times.
Gabe
I took out the len() and made it find password.Length before the for loop, so it is not resolved 4M times.Not much of a time difference.
jcao219
You shouldn't test languages with only 1 test. For instance, the code you test now is more limited to i/o speed instead of processing speed.
Toad
@Toad That's a good point. I modified my IronPython program to start the stopwatch until after the inputfile's contents are loaded, and to stop before the encrypted byte array is written, so no file IO occurs during the time. The time went down to 12493 ms.When I did the same to the C# one, the time went down to 54 ms.
jcao219
I'd be interested in knowing how this scales with larger input files. IronPython 2.6 does some clever JIT-like stuff that means that the program's performance should improve the longer it runs.
Giles Thomas
Testing 55 mb file:IronPython - 226227 msC# - 954 ms.
jcao219
+1  A: 

In the mono environment, using a limited number of benchmarks, IronPython 2.6.1 looks to be 7 to 120 times slower than C# according to the Computer Language Benchmarks Game Site.

DonnyD
>> a limited number of benchmarks << But not as limited as ONE "(I'm not very good at C#)" program ;)
igouy
igouy
A: 

Based on my understanding both languages will be compiled into MSIL so theoretically the performance of the application should be identical or very close, but there is a lot more to it, the human factor.

I can assure you that a program I write in C# could be a lot faster that the same program in iron-python not because C# is faster but because I'm more familiar with C# and I know what choices to make, so if your team is more familiar with C# your application has a better chance at performance if it is written in C# or the other way around.

This is just a personal theory so take it with a grain of salt.

Keivan
Whenever an IronPython application that is made into an executable is distributed, it also comes with it IronPython.dll, Microsoft.Scripting.dll, etcIf the .NET framework someday includes those dll's from a standard installation,I'm sure at least startup speed can increase.
jcao219
+2  A: 

IronPython performance will be always a little bit slower than C# because it is interpreted language. You can see it on jcao219 answer although it is not a good example.

But speed of development actually matters more that performance. Developing application in IronPython is faster than in C# for good IronPython developer. Of course, you should not consider developing application in IronPython when you (and your colleagues) are better in C#.

The overall performance heavily depends on what the code do. Encrypting in IronPython is not a good idea. Spreadsheet application is a good idea - see Resolver One. They thought about converting code from IronPython to C# but they have not done it yet because it is not necessary. When they needed to speed up the code, they have found a way in IronPython itself how to do it.

Lukas Cenovsky
I agree. It took me much less time to write my IronPython version of the xor cryptor. IronPython isn't best for high-performance programs, it is for a high-performance developing experience. It also excels in extending applications that are written in C#.
jcao219
@jcao219 >> It took me much less time << Isn't that because as you said "I'm not very good at C#" ?
igouy
Partly.But in IronPython, the experience felt more natural (because I'm more fluent in Python), and I think I wrote it in less than 3-5 minutes.
jcao219
@jcao219 >> It took me much less time << Isn't that because as you said "I'm more fluent in Python"? In other words, those are comments about your abilities and not about the languages as such.
igouy
I'm not quite sure what your point is. It's fairly evident that IronPython code is much faster to write for a person who is equally adept at both languages. They are both great languages of course. I believe that my comments are directed toward the languages, because I'm not one to boast about my own programming skills.
jcao219