【问题标题】:Speed of code execution: IronPython vs C#?代码执行速度:IronPython vs C#?
【发布时间】:2010-06-21 16:30:21
【问题描述】:

我试图从经理的角度来回答这个问题:如果我们用 IronPython 而不是 C# 编写应用程序,我们会招致什么整体性能损失?

这个问题是针对那些可能已经进行了一些测试、基准测试或已经完成从 C# 到 IronPython 的迁移的人,以便量化惩罚。

【问题讨论】:

  • 如果这是你想要做的,那么你选择了一个非常糟糕的方法来做它。不要问别人速度会是多少 - 自己去寻找。
  • 听起来更像是一个争议解决问题……“我知道,让我们请一个没有既得利益的人来回答这个问题,不管他们说什么,我们都会继续争论。”但也许,我只是在左外野。
  • 除了@John 所说的之外,答案是高度取决于代码将要做什么。此外,一个优秀的程序员将能够编写出比任何由蹩脚程序员编写的 C# 代码都要出色的 IronPython 代码。
  • IronPython 的启动速度很慢,在我看来。稍后我会做一些基准测试。

标签: ironpython


【解决方案1】:

我创建了一个 C# 控制台应用程序(我不太擅长 C#), 它基本上使用 xor 密码加密输入文件。

代码如下:

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;
        }
    }
}

然后是等效的 Python 版本,(我使用 SharpDevelop 4.0 构建可执行文件):

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)

使用相同的 3,827 kb 纯文本文件测试它们的速度, 我明白了:


C#:

  • 尺寸:3928779
  • 经过的毫秒数: 73

.NET 4.0 的 IronPython 2.6

  • 尺寸:3928779
  • 时间(毫秒):16825

所以我认为我们可以得出结论,IronPython 比 C# 慢得多, 在这种特殊情况下。

我可能在这两个文件的代码中的某个地方犯了错误,请随时指出它们。我还在学习。

【讨论】:

  • 其实不是,秒表直到程序启动后才开始滴答作响。在这个任务中,CPython 的速度甚至比 IronPython 慢一点。
  • 更正我上面的评论,我刚刚测试过,CPython 实际上更快。
  • 我想知道enumerate 是否是造成大部分差异的原因。它创建了 C# 版本没有的 4M 元组对象。这不应该有 16 秒的差异,但它可能是最大的差异。
  • 你不应该只用 1 个测试来测试语言。例如,您现在测试的代码更多地限于 i/o 速度而不是处理速度。
  • @Toad 说得好。我修改了我的 IronPython 程序以启动秒表,直到加载输入文件的内容之后,并在写入加密字节数组之前停止,因此在此期间不会发生文件 IO。时间下降到 12493 毫秒。当我对 C# 做同样的事情时,时间下降到 54 毫秒。
【解决方案2】:

IronPython 的性能总是比 C# 慢一点,因为它是解释型语言。你可以在jcao219 answer 上看到它,虽然它不是一个很好的例子。

但开发速度实际上比性能更重要。 对于优秀的 IronPython 开发人员来说,使用 IronPython 开发应用程序比使用 C# 更快。当然,当您(和您的同事)更擅长 C# 时,您不应该考虑使用 IronPython 开发应用程序。

整体性能很大程度上取决于代码的作用。 IronPython 中的加密不是一个好主意。电子表格应用程序是一个好主意 - 请参阅解析器一。他们考虑将代码从 IronPython 转换为 C#,但他们还没有这样做,因为没有必要。当他们需要加快代码速度时,他们已经在 IronPython 本身中找到了一种方法。

【讨论】:

  • 我同意。我花了更少的时间来编写我的 IronPython 版本的异或密码器。 IronPython 不是最好的高性能程序,它是高性能的开发体验。它还擅长扩展用 C# 编写的应用程序。
  • @jcao219 >> 我花了更少的时间
  • 部分。但在 IronPython 中,体验感觉更自然(因为我对 Python 更流利),而且我认为我在不到 3-5 分钟的时间内就写好了。
  • @jcao219 >> 我花了更少的时间
  • 我不太确定你的意思是什么。很明显,对于同样擅长两种语言的人来说,编写 IronPython 代码要快得多。当然,它们都是很棒的语言。我相信我的 cmets 是针对语言的,因为我不是一个吹嘘自己的编程技能的人。
【解决方案3】:

根据Computer Language Benchmarks Game Site,在单声道环境中,使用有限数量的基准测试,IronPython 2.6.1 看起来比 C# 慢 7 到 120 倍。

【讨论】:

【解决方案4】:

根据我的理解,两种语言都会被编译成 MSIL,所以理论上应用程序的性能应该是相同或非常接近的,但人为因素还有很多。

我可以向你保证,我用 C# 编写的程序可能比 Iron-python 中的相同程序快得多,这不是因为 C# 更快,而是因为我更熟悉 C#,而且我知道要做出哪些选择,所以如果您的团队更熟悉 C#,那么如果您的应用程序是用 C# 或其他方式编写的,那么您的应用程序就有更好的表现机会。

这只是个人理论,所以请持保留态度。

【讨论】:

  • 每当分发一个做成可执行文件的 IronPython 应用程序时,它还附带 IronPython.dll、Microsoft.Scripting.dll 等 如果 .NET 框架有一天会从标准安装中包含这些 dll ,我敢肯定至少启动速度可以提高。
  • IronPython 速度较慢,因为它是基于 DLR(动态语言运行时)构建的。我也认为它应该和 c# 一样快 - 说实话不是。
  • -1: Re“根据我的理解......所以理论上应用程序的性能应该相同或非常接近。”然而你的理解是错误的。是的,它们都被编译成 MSIL。但是,既然您不知道它们的编译方式可能有什么不同,也没有对有关该主题的信息进行基本搜索,为什么还要麻烦发布答案呢?
猜你喜欢
  • 2023-03-12
  • 2019-01-15
  • 1970-01-01
  • 2021-08-17
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 2023-04-10
相关资源
最近更新 更多