整数値を整数入力に返す関数があります。出力値は比較的まばらです。この関数は、入力値 1....2^16 に対して約 2^14 の一意の出力のみを返します。特定の出力を生成する入力をすばやく見つけることができるデータセットを作成したいと考えています。
現在、データセットをリストのマップに保存しており、各出力値が入力値のリストのキーとして機能しています。これは遅いようで、スタック スペース全体を使用しているように見えます。データセットを作成/保存/アクセスするより効率的な方法はありますか?
追加: 私の sparesearray() 関数にかかる時間は、入力値 (リストに格納された値) に対する出力値 (つまりキー) の比率によって大きく異なることがわかりました。以下は、多数のリストを必要とし、それぞれに少数の値しかない関数にかかった時間です。
? sparsearray(2^16,x->x\7);
time = 126 ms.
それぞれが多くの値を持ついくつかのリストのみを必要とする関数にかかる時間は次のとおりです。
? sparsearray(2^12,x->x%7);
time = 218 ms.
? sparsearray(2^13,x->x%7);
time = 892 ms.
? sparsearray(2^14,x->x%7);
time = 3,609 ms.
ご覧のとおり、時間は指数関数的に増加します。
これが私のコードです:
\\ sparsearray takes two arguments, an integer "n" and a closure "myfun",
\\ and returns a Map() in which each key a number, and each key is associated
\\ with a List() of the input numbers for which the closure produces that output.
\\ E.g.:
\\ ? sparsearray(10,x->x%3)
\\ %1 = Map([0, List([3, 6, 9]); 1, List([1, 4, 7, 10]); 2, List([2, 5, 8])])
sparsearray(n,myfun=(x)->x)=
{
my(m=Map(),output,oldvalue=List());
for(loop=1,n,
output=myfun(loop);
if(!mapisdefined(m,output),
/* then */
oldvalue=List(),
/* else */
oldvalue=mapget(m,output));
listput(oldvalue,loop);
mapput(m,output,oldvalue));
m
}