当前位置: 首页 > 面试题库 >

Python比编译的Haskell快吗?

姬经义
2023-03-14
问题内容

我有一个用Python和Haskell编写的简单脚本。它读取一个由1000000个换行符分隔的整数的文件,将该文件解析为整数列表,对其进行快速排序,然后将其写入另一个已排序的文件中。该文件与未排序的文件具有相同的格式。简单。

这是Haskell:

quicksort :: Ord a => [a] -> [a]
quicksort []     = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where
        lesser  = filter (< p) xs
        greater = filter (>= p) xs

main = do
    file <- readFile "data"
    let un = lines file
    let f = map (\x -> read x::Int ) un
    let done = quicksort f
    writeFile "sorted" (unlines (map show done))

这是Python:

def qs(ar):
    if len(ar) == 0:
        return ar

    p = ar[0]
    return qs([i for i in ar if i < p]) + [p] + qs([i for i in ar if i > p])


def read_file(fn):
    f = open(fn)
    data = f.read()
    f.close()
    return data

def write_file(fn, data):
    f = open('sorted', 'w')
    f.write(data)
    f.close()


def main():
    data = read_file('data')

    lines = data.split('\n')
    lines = [int(l) for l in lines]

    done = qs(lines)
    done = [str(l) for l in done]

    write_file('sorted', "\n".join(done))

if __name__ == '__main__':
    main()

非常简单。现在我用以下代码编译Haskell代码

$ ghc -O2 --make quick.hs

我给这两个时间计时:

$ time ./quick
$ time python qs.py

结果:

Haskell:

real    0m10.820s
user    0m10.656s
sys 0m0.154s

蟒蛇:

real    0m9.888s
user    0m9.669s
sys 0m0.203s

Python如何比本地代码Haskell更快?

谢谢

编辑

  • Python版本:2.7.1
  • GHC版本:7.0.4
  • Mac OSX,10.7.3
  • 2.4GHz英特尔酷睿i5

清单产生者

from random import shuffle
a = [str(a) for a in xrange(0, 1000*1000)]
shuffle(a)
s = "\n".join(a)
f = open('data', 'w')
f.write(s)
f.close()

因此,所有数字都是唯一的。


问题答案:

简而言之,不要使用read。替换read为以下函数:

import Numeric

fastRead :: String -> Int
fastRead s = case readDec s of [(n, "")] -> n

我得到了相当不错的加速:

~/programming% time ./test.slow
./test.slow  9.82s user 0.06s system 99% cpu 9.901 total
~/programming% time ./test.fast
./test.fast  6.99s user 0.05s system 99% cpu 7.064 total
~/programming% time ./test.bytestring
./test.bytestring  4.94s user 0.06s system 99% cpu 5.026 total

只是为了好玩,上述结果包括一个使用ByteStringULTIMATE BARE-METAL
SPEED的版本(因此完全忽略了文件编码问题,因此未能通过“ 21世纪的就绪”测试)。它还有一些其他差异。例如,它附带了标准库的排序功能。完整代码如下。

import qualified Data.ByteString as BS
import Data.Attoparsec.ByteString.Char8
import Control.Applicative
import Data.List

parser = many (decimal <* char '\n')

reallyParse p bs = case parse p bs of
    Partial f -> f BS.empty
    v -> v

main = do
    numbers <- BS.readFile "data"
    case reallyParse parser numbers of
        Done t r | BS.null t -> writeFile "sorted" . unlines . map show . sort $ r


 类似资料:
  • 上世纪九十年代,Glasgow Haskell编译器(诞生于格拉斯哥[Glasgow]大学)开始时作为英国政府资助的学术研究项目的一部分,有着如下几个计划目标: - 可以免费获得的,健壮且可移植的Haskell编译器,能够产出高性能的代码 - 模块化设计,便于其他研究人员扩展和开发 - 让人学习真实程序如何运作,来设计和构建更好的编译器 GHC有了20多年的历史了,从诞生之日起,他的开发一直保持着

  • 问题内容: 我想使用Biot- Savart定律 来计算某些导体的磁场,并且我想使用1000x1000x1000的矩阵。在使用MATLAB之前,但现在我想使用Python。Python比MATLAB慢吗?如何使Python更快? 编辑:也许最好的方法是使用C / C ++计算大型数组,然后将其传输到Python。然后我想用VPython可视化。 EDIT2:在我的情况下哪个更好:C还是C ++?

  • 问题内容: 我听说在某些情况下,由于JIT优化,Java程序或Java程序的某些部分比C ++(或其他预编译的代码)中的“相同”代码执行得更快。这是由于编译器能够确定某些变量的范围,避免某些条件并在运行时提取类似的技巧。 您能否举一个(或更佳的)例子,在哪里适用?也许概述了编译器能够优化字节码的确切条件,超出了预编译代码的范围? 注意: 此问题 不是 关于将Java与C ++进行比较。关于JIT编

  • 下面的代码通过指数慢的算法计算斐波那契数: 我在运行时计算第45个斐波那契数,在编译时计算第91个。 有趣的事实是,GCC4.9编译代码并在几分之一秒内计算出,但吐出需要一段时间。 以上是否意味着GCC会生成函数的两个编译版本,其中一个是快的,另一个是指数级慢的? 问题不是编译器如何优化计算(是的!它确实使用了某种记忆),而是如果它知道如何优化函数,为什么它不对做同样的操作呢?并且,函数有两个单独

  • 问题内容: 如何在Python中进行条件编译? 使用DEF吗? 问题答案: Python的编译方式与C,C ++甚至Java都不一样,Python文件是“即时”编译的,您可以认为它类似于诸如Basic或Perl的解释语言。1个 您可以仅通过使用if语句来执行与条件编译等效的操作。例如: 您可以对创建类,变量设置以及几乎所有内容执行相同的操作。 模拟IFDEF的最接近方法是使用hasattr函数。例

  • 问题内容: 我一直认为Python的优势在于代码的可读性和开发速度,但是时间和内存的使用却不如C ++。 这些统计数据让我非常震惊。 您的经验告诉您关于Python与C ++的时间和内存使用情况? 问题答案: 我认为您错误地读取了这些统计信息。他们表明,Python比C ++ 慢 大约400倍,除了一个案例,Python更像是一种内存消耗。不过,就源代码大小而言,Python胜出。 我的Pytho