.·.·. 发表于 2018-6-22 11:42:01

关于pari/gp的效率,以及想问一下该如何手动编译……编译几乎总是不过

本帖最后由 .·.·. 于 2018-6-22 11:47 编辑

折腾了好久……终于发现,凭自己大概率是不可能成功的……
首先,想问一下有没有给pari/gp的循环加速的方法
一个简单的循环
for(a=1,100000000,c++)
需要跑10秒……
作为对比,R(一个超慢的统计软件)只需要1/3的时间就可以跑完b=0;for(a in 1:100000000)b=b+1
pari/gp究竟丧心病狂地做了什么?

以及,看到有一个gp2c很不错……windows强行编译……强行浪费了3个小时
cygwin版本一次成功……然而Cygwin多线程比windows单线程还慢,同时,gp2c的生成代码似乎也是减速而非加速……

换MSYS2,每次编译都费尽千辛万苦(比如在编GMP的时候替换掉gcc以过掉一些出了问题的汇编)
当然,最后编译是成功的……然而执行的时候不知为什么总提示某一个地址不是32位程序能用的……
我明明编的64位……
./configure --with-gmp=/d/pen/pari-2.9.5/msys2-ver/gmp-6.1.2 --with-gmp-include=/d/pen/pari-2.9.5/msys2-ver/gmp-6.1.2 --with-gmp-lib=/d/pen/pari-2.9.5/msys2-ver/gmp-6.1.2/.libs --with-readline --with-runtime-perl=/usr/bin --enable-tls --mt=pthread --host=msys2-x86_64

pa2c,由于最后链接的是人家的pari,最后的编译直接失败,于是跑不动……
./configure --with-perl=/usr/bin --with-paricfg=/d/pen/pari-2.9.5/Pari64-2-9-5/lib/pari/pari.cfg

有没有大牛分享一下编译pari/gp的经验呢?
难道只有用linux才能解决一切问题吗?

最后还有一个问题,如何判断某一个元素是否在集合中
比如我们有一个程序,每次会生成一个整数i
我们想判断这个整数i是否跟以往产生的整数重复
于是我们可以构造一个集合a=Set([])
之后每次执行
len=length(a)
a=Set()
if(length(a)-len,没重复,有重复)
有没有更快更方便的方法呢?比如python可以直接用i in a和a.add(i)来完成一切操作……然而萌新表示,看看这个程序的文档实在不知道该从哪里找更好的表述方法……
还望dalao不吝赐教

mathe 发表于 2018-6-22 16:49:12

pari/gp的确效率不是很好,能够使用的内存也是预先分配的,不能使用太多内存。Linux比Windows效率明显要高,但是还不是特别好.

.·.·. 发表于 2018-6-22 18:36:07

mathe 发表于 2018-6-22 16:49
pari/gp的确效率不是很好,能够使用的内存也是预先分配的,不能使用太多内存。Linux比Windows效率明显要高 ...

弄了集合操作
差不多是用a=Set(compat(l,a))跟length(a)执行的
刚开始每次循环一秒就够
算了五个小时
现在一次循环十几秒
简直吓人

话说算数论的话有什么更快的程序吗
难道真的要上网下载盗版mathematica吗……

补充内容 (2018-6-23 02:44):
找到程序为什么从1.7s涨到17s的原因了……
原因是记错了(……)

wayne 发表于 2018-6-22 22:38:06

len=length(a)
a=Set()
if(length(a)-len,没重复,有重复)
将插入换成集合的搜索操作比较合适,即换成setsearch函数。


setsearch(S, x, {flag = 0})
Determines whether x belongs to the set S (see setisset).

We first describe the default behaviour, when flag is zero or omitted. If x belongs to the set S, returns the index j such that S = x, otherwise returns 0.

? T = ; S = Set(T);
? setsearch(S, 2)
%2 = 1
? setsearch(S, 4)      \\ not found
%3 = 0
? setsearch(T, 7)      \\ search in a randomly sorted vector
%4 = 0 \\ WRONG !
If S is not a set, we also allow sorted lists with respect to the cmp sorting function, without repeated entries, as per listsort(L,1); otherwise the result is undefined.


根据PARI/Gp的Set的setsearch的解释来看,是有序的集合,所以其实现应该是平衡树,插入和查找都是O(lgn)复杂度。
而根据你的需求来看,有两个高频操作,插入和查找。所以最理想的情况应该是字典来实现。插入和查找都是O(1)复杂度。如c++11 unordered_map结构。
======

.·.·. 发表于 2018-6-23 01:41:54

本帖最后由 .·.·. 于 2018-6-23 02:46 编辑

wayne 发表于 2018-6-22 22:38
将插入换成集合的搜索操作比较合适,即换成setsearch函数。



……
找到程序为什么从1.7s涨到17s的原因了……
原因是记错了(……)

很抱歉虽然这一步是唯一可能会随时间变化变得复杂的步骤,但单凭一步的确不足以达到我描述的效果……
现在用linux,准备强行开多线程:)
我的系统差点就重装成ubuntu了……

悬崖勒马……
页: [1]
查看完整版本: 关于pari/gp的效率,以及想问一下该如何手动编译……编译几乎总是不过