仍在玩推特趋势。 我收集了足够的数据,我想加快处理速度。 我想通过使用以趋势词为索引的关联数组为每个趋势词分配一个整数索引。 下面介绍了三种向表中添加新词或获取旧词索引的技术。
当单词不在表中时,第一个使用 TRY 捕获异常。 如果单词存在则最快,如果发生异常则最慢(到目前为止)。
第二个使用 CONTAINS 来测试单词是否存在,然后添加它或查找它。 添加速度最快,查找速度最慢(因为它会查找两次。)
最后一个使用关联数组默认值来查看检索到的值是否已经存在。 它提供了一个不错的折衷速度。
所有示例都有一个运行两次的“t”循环。 第一次xN数组为空,必须填写。 第二次所有值都已经存在。
// Three ways to build a lookup table. No clear winner!
// Goal: assign an integer, starting at 1, to each new
// entry. For timing purposes, use the integer as the
// key and the value. The key will be a string in real
// code. The value will be used as an index elsewhere.
explain = {"create new entry","use existing entry"};
N = 1e5; // several seconds at 1e5
/*
Use TRY to determine when an entry needs to be created.
On the "catch" create the entry. If there is no catch,
the value is already fetched. The "t" loop runs 20X
slower the first time because the "catch" is expensive.
But the second time the "t" loop is the fastest solution.
*/
x1 = [=> ];
For( t = 1, t <= 2, t += 1,
start = HP Time();
For( ix = 1, ix < N, ix += 1,
Try( y = x1[ix], y = (x1[ix] = ix) )
);
stop = HP Time();
Write( Eval Insert( "\!nTry method: ^char((stop - start)/1e6,5,3)^ seconds ^explain[t]^" ) );
);
/*
Use CONTAINS to determine if the entry needs to be created.
Use the if's "then" clause to fetch the existing index or
"else" clause to create a new entry. The "t" loop has the
fastest speed on the first run, by far, and the slowest
speed on the second run.
*/
x2 = [=> ];
For( t = 1, t <= 2, t += 1,
start = HP Time();
For( ix = 1, ix < N, ix += 1,
If( Contains( x2, ix ),
y = x2[ix],
y = (x2[ix] = ix)
)
);
stop = HP Time();
Write( Eval Insert( "\!nContains method: ^char((stop - start)/1e6,5,3)^ seconds ^explain[t]^" ) );
);
/*
Use a DEFAULT value to determine if the entry needs to be
created. Fetch the value for the entry, check for the default
and create if needed. This gives an between value for both
"t" loops. It might be a good compromise choice if no extra
testing will be done and 0 can be used as a default. !y,
below, is faster than y==0.
*/
x3 = [=> 0];
For( t = 1, t <= 2, t += 1,
start = HP Time();
For( ix = 1, ix < N, ix += 1,
y = x3[ix];
If( !y, y = (x3[ix] = ix) );
);
stop = HP Time();
Write( Eval Insert( "\!ndefault 0 method: ^char((stop - start)/1e6,5,3)^ seconds ^explain[t]^" ) );
);
// quick test... the lack of a default value in x1 and x2
// makes them compare not equal, so add it before testing.
x1 << setdefaultvalue( 0 );
x2 << setdefaultvalue( 0 );
Show( x1 == x2, x1 == x3 );
尝试方法:2.851秒创建新条目
尝试方法: 0.099秒使用现有条目
包含方法: 0.209秒创建新条目
包含方法:0.151 秒使用现有条目
默认 0 方法: 0.259秒创建新条目
默认 0 方法: 0.117秒使用现有条目
x1 == x2 = 1;
x1 == x3 = 1;
在红色中,TRY 和 CONTAINS 为现有和新条目提供了最快的时间。 在绿色中,DEFAULT 0 可能是一个很好的折衷方案。 这实际上取决于将创建多少条目,以及它们将被查找多少次。