Python 比编译的 Haskell 更快? [英] Python faster than compiled Haskell?
问题描述
我有一个用 Python 和 Haskell 编写的简单脚本.它读取包含 1,000,000 个换行符分隔的整数的文件,将该文件解析为整数列表,对其进行快速排序,然后将其写入已排序的不同文件.该文件与未排序的文件格式相同.简单.
I have a simple script written in both Python and Haskell. It reads a file with 1,000,000 newline separated integers, parses that file into a list of integers, quick sorts it and then writes it to a different file sorted. This file has the same format as the unsorted one. Simple.
这里是 Haskell:
Here is 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:
And here is 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('
')
lines = [int(l) for l in lines]
done = qs(lines)
done = [str(l) for l in done]
write_file('sorted', "
".join(done))
if __name__ == '__main__':
main()
很简单.现在我用
$ ghc -O2 --make quick.hs
我给这两个计时:
$ time ./quick
$ time python qs.py
结果:
哈斯克尔:
real 0m10.820s
user 0m10.656s
sys 0m0.154s
蟒蛇:
real 0m9.888s
user 0m9.669s
sys 0m0.203s
Python 怎么可能比本地代码 Haskell 更快?
How can Python possibly be faster than native code 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 = "
".join(a)
f = open('data', 'w')
f.write(s)
f.close()
所以所有数字都是唯一的.
So all numbers are unique.
推荐答案
总之,不要使用read
.用这样的函数替换 read
:
In short, don't use read
. Replace read
with a function like this:
import Numeric
fastRead :: String -> Int
fastRead s = case readDec s of [(n, "")] -> n
我得到了相当不错的加速:
I get a pretty fair speedup:
~/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
只是为了好玩,上面的结果包括一个使用 ByteString
的版本(因此完全忽略了文件编码的问题而未能通过为 21 世纪做好准备"的测试)用于 ULTIMATE BARE-METAL速度.它还具有其他一些差异;例如,它发送到标准库的排序功能.完整代码如下.
Just for fun, the above results include a version that uses ByteString
(and hence fails the "ready for the 21st century" test by totally ignoring the problem of file encodings) for ULTIMATE BARE-METAL SPEED. It also has a few other differences; for example, it ships out to the standard library's sort function. The full code is below.
import qualified Data.ByteString as BS
import Data.Attoparsec.ByteString.Char8
import Control.Applicative
import Data.List
parser = many (decimal <* char '
')
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
这篇关于Python 比编译的 Haskell 更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!