# 分叉阶乘

12

``````#!/usr/bin/perl -w
use strict;
use bigint;
die "usage: f.perl N (outputs N!)" unless (\$ARGV[0] > 1);
print STDOUT &main::rangeProduct(1,\$ARGV[0])."\n";
sub main::rangeProduct {
my(\$l, \$h) = @_;
return \$l    if (\$l==\$h);
return \$l*\$h if (\$l==(\$h-1));
# arghhh - multiplying more than 2 numbers at a time is too much work
# find the midpoint and split the work up :-)
my \$m = int((\$h+\$l)/2);
my \$pid = open(my \$KID, "-|");
if (\$pid){ # parent
my \$X = &main::rangeProduct(\$l,\$m);
my \$Y = <\$KID>;
chomp(\$Y);
close(\$KID);
die "kid failed" unless defined \$Y;
return \$X*\$Y;
} else {
# kid
print STDOUT &main::rangeProduct(\$m+1,\$h)."\n";
exit(0);
}
}
``````

10

aaaaaaaaaaaaa

gnibbler 2011年

mellamokb 2011年

2
@mellamokb：我希望对多核系统有所不同。

@乔伊：嗯。错过了这么小的细节：s同意
mellamokb'3

7

## Mathematica

`````` f[n_, g_] := g[Product[N@i, {i, 1, n, 2}] Product[N@i, {i, 2, n, 2}]]
``````

``````f[n_, g_] := First@AbsoluteTiming[g[Product[N@i,{i,1,n,2}] Product[N@i,{i,2,n,2}]]]
``````

``````ListLinePlot[{Table[f[i, Identity],    {i, 100000, 900000, 100000}],
Table[f[i, Parallelize], {i, 100000, 900000, 100000}]}]
``````

@Peter谢谢，最后一个“]”没有通过复制缓冲区。已更正。
belisarius博士2011年

1

7

### 176 167源+ 33 10编译器标志

``````import Control.Parallel.Strategies
s(x:y:z)=[[x,y::Integer]]++s z;s x=[x]
p=product
f n=p\$concat\$(until((<3).length)\$s.parMap rseq p)\$s[1..n]
``````

（随时阅读的中间部分`f`之间`concat`，并`s`为“直到我心脏长”）

``````ghc -threaded prog.hs
``````

``````SPARKS: 50020 (29020 converted, 1925 pruned)

INIT  time    0.00s  (  0.00s elapsed)
MUT   time    0.20s  (  0.19s elapsed)
GC    time    0.12s  (  0.07s elapsed)
EXIT  time    0.00s  (  0.00s elapsed)
Total time    0.31s  (  0.27s elapsed)
``````

``````          Parallel   Sequential
10000!      0.03s        0.04s
50000!      0.27s        0.78s
100000!      0.74s        3.08s
500000!      7.04s       86.51s
``````

``````factorial :: Integer -> Integer
factorial n = product [1..n]
``````

1
IMO，您不必为编译器和解释器计算args。
FUZxxl 2011年

6

## Ruby-111 + 56 = 167个字符

``````c,n=*\$*.map(&:to_i)
p=(0...c).map{|k|IO.popen("ruby f2.rb #{k} #{c} #{n}")}
``````

``````c,h,n=*\$*.map(&:to_i)
p (c*n/h+1..(c+1)*n/h).inject(:*)
``````

``````time ruby fact.rb 5 5000 #=> 61.84s
``````

Ruby1.9.2：

``````time ruby fact.rb 5 50000 #=> 3.09s
``````

（注意额外的`0`

1

Michael Kohl

@Michael：谢谢:)。还只是注意到，如果有人在运行此程序时遇到问题，我`8`应该在哪里应该有一个`*`
Nemo157 2011年

6

## Java，523 519 434 430 429个字符

``````import java.math.*;public class G extends Thread{BigInteger o,i,r=BigInteger.ONE,h;G g;G(BigInteger O,int
I,int n){o=O;i=new BigInteger(""+I);if(n>1)g=new G(O.subtract(r),I,n-1);h=n==I?i:r;start();}public void
run(){while(o.signum()>0){r=r.multiply(o);o=o.subtract(i);}try{g.join();r=r.multiply(g.r);}catch(Exception
e){}if(h==i)System.out.println(r);}public static void main(String[] args){new G(new BigInteger(args[0]),4,4);}}
``````

50000！在以下框架（原始版本的非ololfed版本，并减少了一些不良实践，尽管仍然有很多）上进行了测试（在我的4核Linux机器上）

``````7685ms
2338ms
1361ms
1093ms
7724ms
``````

``````import java.math.*;

private BigInteger off, inc;
private volatile BigInteger res;

private ForkingFactorials(int off, int inc) {
this.off = new BigInteger(Integer.toString(off));
this.inc = new BigInteger(Integer.toString(inc));
}

public void run() {
BigInteger p = new BigInteger("1");
while (off.signum() > 0) {
p = p.multiply(off);
off = off.subtract(inc);
}
res = p;
}

public static void main(String[] args) throws Exception {
int n = Integer.parseInt(args[0]);
System.out.println(f(n, 1));
System.out.println(f(n, 2));
System.out.println(f(n, 3));
System.out.println(f(n, 4));
System.out.println(f(n, 1));
}

private static BigInteger f(int n, int numThreads) throws Exception {
long now = System.currentTimeMillis();
for (int i = 0; i < n && i < numThreads; i++) {
th[i].start();
}
BigInteger f = new BigInteger("1");
for (int i = 0; i < n && i < numThreads; i++) {
th[i].join();
f = f.multiply(th[i].res);
}
long t = System.currentTimeMillis() - now;
System.err.println("Took " + t + "ms");
return f;
}
}
``````

5

### CSHARP - 206 215个字符

``````using System;using System.Numerics;using System.Threading.Tasks;class a{static void Main(){var n=int.Parse(Console.ReadLine());var r=new BigInteger(1);Parallel.For(1,n+1,i=>{lock(this)r*=i;});Console.WriteLine(r);}}
``````

``````n = 10,000, time: 59ms.
n = 20,000, time: 50ms.
n = 30,000, time: 38ms.
n = 40,000, time: 100ms.
n = 50,000, time: 139ms.
n = 60,000, time: 164ms.
n = 70,000, time: 222ms.
n = 80,000, time: 266ms.
n = 90,000, time: 401ms.
n = 100,000, time: 424ms.
n = 110,000, time: 501ms.
n = 120,000, time: 583ms.
n = 130,000, time: 659ms.
n = 140,000, time: 832ms.
n = 150,000, time: 1143ms.
n = 160,000, time: 804ms.
n = 170,000, time: 653ms.
n = 180,000, time: 1031ms.
n = 190,000, time: 1034ms.
n = 200,000, time: 1765ms.
n = 210,000, time: 1059ms.
n = 220,000, time: 1214ms.
n = 230,000, time: 1362ms.
n = 240,000, time: 2737ms.
n = 250,000, time: 1761ms.
n = 260,000, time: 1823ms.
n = 270,000, time: 3357ms.
n = 280,000, time: 2110ms.
``````

4

## 佩尔（140）

``````use bigint;\$m=<>;open A,'>',
undef;\$i=\$p=fork&&1;\$n=++\$i;
{\$i+=2;\$n*=\$i,redo if\$i<=\$m}
if(\$p){wait;seek A,0,0;\$_=<A
>;print\$n*\$_}else{print A\$n}
``````

• 计算拆分：一侧为偶数，另一侧为奇数（比这复杂的东西将需要很多字符来适当地平衡计算负载。
• IPC使用共享的匿名文件。

• 10000！以分叉的2.3s，未分叉的3.4s打印
• 100000！印有5'08.8分叉，7'07.9未分叉

4

## 阶（345个266 244个232个 214字符）

``````object F extends App{import actors.Actor._;var(t,c,r)=(args(1).toInt,self,1:BigInt);val n=args(0).toInt min t;for(i<-0 to n-1)actor{c!(i*t/n+1 to(i+1)*t/n).product};for(i<-1 to n)receive{case m:Int=>r*=m};print(r)}
``````

``````import actors.Actor._
object ForkingFactorials extends App
{
var (target,caller,result)=(args(1).toInt,self,1:BigInt)
actor
{
}
{
case m:Int=>result*=m
}
print(result)
}
``````

3

### Scala-2.9.0 170

``````object P extends App{
def d(n:Int,c:Int)=(for(i<-1 to c)yield(i to n by c)).par
println((BigInt(1)/: d(args(0).toInt,args(1).toInt).map(x=>(BigInt(1)/: x)(_*_)))(_*_))}
``````

### 松开

``````object ParallelFactorials extends App
{
def distribute (n: Int, cores: Int) = {
val factorgroup = for (i <- 1 to cores)
yield (i to n by cores)
factorgroup.par
}

val parallellist = distribute (args(0).toInt, args(1).toInt)

println ((BigInt (1) /: parallellist.map (x => (BigInt(1) /: x) (_ * _)))(_ * _))

}
``````

• 1 5 9
• 2 6 10
• 3 7
• 4 8

`````` (1 to n).sliding ((n/cores), (n/cores)
``````
• 1 2 3
• 4 5 6
• 7 8 9
• 10

2.9版的Scala包含并行Collections，它们自己处理并行调用。

2

## Erlang-295个字符。

``````-module(f).
-export([m/2,f/4]).
m(N,C)->g(N,C,C,[]).
r([],B)->B;
s(H,L)->spawn(f,f,[self(),H,L,1]).
g(N,1,H,A)->r([s(N div H,1)|A],1);
g(N,C,H,A)->g(N,C-1,H,[s(N*C div H,N*(C-1) div H)|A]).
f(P,H,H,A)->P!{self(),A};
f(P,H,L,A)->f(P,H-1,L,A*H).
``````

``````c(f).
f:m(NUM_TO_CALC, NUM_OF_PROCESSES).
``````