我有一种将值转换为 newBase 长度长度的方法。
英语的逻辑是:
If we calculated every possible combination of numbers from 0 to (c-1)
with a length of x
what set would occur at point i
虽然下面的方法确实很有效,但由于使用了非常大的数字,可能需要很长时间才能完成:
例如,value =(((65536 ^ 480000)-1)/ 2),newbase =(65536),length =(480000)在64位架构(四核PC)上需要大约一个小时才能完成。
private int[] GetValues(BigInteger value, int newBase, int length)
{
Stack<int> result = new Stack<int>();
while (value > 0)
{
result.Push((int)(value % newBase));
if (value < newBase)
value = 0;
else
value = value / newBase;
}
for (var i = result.Count; i < length; i++)
{
result.Push(0);
}
return result.ToArray();
}
我的问题是,如何将此方法更改为允许多个线程计算出部分数字的内容?
我正在使用C#,但如果你不熟悉它,那么伪代码也可以。
注意:该方法来自此问题:Cartesian product subset returning set of mostly 0
答案 0 :(得分:2)
如果GetValues
方法确实是瓶颈,那么可以采取一些措施加快速度。
首先,每次循环时你都要除以newBase
。由于newBase
是int
,并且BigInteger
除法方法除以BigInteger
,因此您可能需要花费int
- 至{{每次迭代都会转换{1}}。你可能会考虑:
BigInteger
此外,您可以通过拨打DivRem:
将分数减半BigInteger bigNewBase = newBase;
正如评论中提到的那样,另一个优化是将数字存储在预先分配的数组中。您必须致电Array.Reverse以正确的顺序获取它们,但这几乎没有时间。
顺便说一下,这种方法不适合并行化,因为计算每个数字取决于前一个数字的计算。