erlang数值计算的性能

时间:2015-07-03 03:24:28

标签: erlang

C版:

require 'open-uri'

def http_download(uri, filename)
  bytes_total = nil
  index = 1
  begin
    open(
      uri,
      read_timeout: 500,
      content_length_proc: lambda { |content_length|
        bytes_total = content_length
      },
      progress_proc: lambda { |bytes_transferred|
        if bytes_total
          print("\r#{bytes_transferred} of #{bytes_total} bytes")
        else
          print("\r#{bytes_transferred} bytes (total size unknown)")
        end
      }
    ) do |io|
      # if "application/json" == io.content_type
      if io.is_a? StringIO
        raise " --> Failed, server is processing. Retry the request ##{index}"
      else # Tempfile
        puts "\n--> Succeed, writing to #{filename}"
        File.open(filename, 'w'){|wf| wf.write io.read}
      end
    end
  rescue => e
    puts e
    return if e.is_a? OpenURI::HTTPError # Processing error

    index += 1
    return if index > 10

    sleep index and retry
  end
end

结果:

#include <stdio.h>
#include <stdlib.h>
unsigned int test(unsigned int n_count) {
  unsigned int c = 1;
  unsigned int i;
  for (i=0; i< n_count;i++) {
    c += 2 * 34 + 1;
    c /= 2;
    c *= 39;
  }
  return c;
}
int main(int argc, char* argv[])
{
  printf("%u\n", test(atoi(argv[1])));
}

erlang版本:

$ gcc p2.c
$ time ./a.out 100000000
563970997

real    0m0.865s
user    0m0.864s
sys 0m0.004s

结果:

-module(test2).
-export([main/1]).
-mode(compile).
calc(Cnt, Total) when Cnt > 0 ->
  if Total >= 4294967296 -> Total2 = Total rem 4294967296;
    true -> Total2 = Total end,
  calc(Cnt - 1, trunc((Total2 + 2 * 34 + 1) / 2) * 39);
calc(0, Total)->
  if Total >= 4294967296 -> Total2 = Total rem 4294967296;
    true -> Total2 = Total end,
  io:format("~p ~n", [Total2]),
  ok.
main([A])->
  Cnt = list_to_integer(A),
  calc(Cnt, 1).

如何提高erlang版本的性能? 在erlang中,我必须模拟整数溢出的情况,有更好的方法吗? 即使使用hipe,性能也远不是C。

修改

Python版本:

$ erlc +native +"{hipe, [to_llvm]}" test2.erl
$ time escript test2.beam 100000000
563970997 

real    0m4.940s
user    0m4.892s
sys 0m0.056s
$ erlc +native test2.erl
$ time escript test2.beam 100000000
563970997 

real    0m5.381s
user    0m5.320s
sys 0m0.064s
$ erlc test2.erl
$ time escript test2.beam 100000000
563970997 

real    0m9.868s
user    0m9.808s
sys 0m0.056s

结果:

def test(n_count):
    c = 1
    for i in xrange(n_count):
        c += 2 * 34 + 1
        c /= 2
        c *= 39
        if c >= 4294967296:
          c = c % 4294967296
    return c
print test(100000000)

2 个答案:

答案 0 :(得分:1)

我认为以下链接可能特别有用,您将能够“烘焙”#39;你的C代码进入你的Erlang应用程序:

http://www.erlang.org/doc/tutorial/c_port.html

答案 1 :(得分:0)

Erlang在数字滚动任务方面确实不太好。很好,如果你想要占用字节并发送它们。
当您将一些瓶颈模块重写为本机时,通常严重的Erlang开发周期包括最终优化。
是的,Erlang看起来像是好的计算(和像Wings3D这样的项目显示),但也许你必须选择其他工具?