여전히 트위터 트렌드를 가지고 놀고 있습니다. 처리 속도를 높이고 싶을 만큼 충분한 데이터가 수집되었습니다. 트렌드 단어로 인덱싱된 연관 배열을 사용하여 각 트렌드 단어에 정수 인덱스를 할당하고 싶습니다. 아래에는 테이블에 새 단어를 추가하거나 이전 단어에 대한 인덱스를 가져오는 세 가지 기술이 있습니다.
첫 번째는 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은 좋은 절충안일 수 있습니다. 얼마나 많은 항목이 생성되고 얼마나 많이 조회되는지에 따라 다릅니다.