@@ -152,6 +152,17 @@ namespace Timbl{
152152 metricTest[i] = new overlapTestFunction ();
153153 }
154154 }
155+ // Precompute, in permuted order, the metric test function and an Overlap
156+ // flag for each feature, so test() can use a flat index and take a direct
157+ // path for Overlap features.
158+ permTest.resize (_size,0 );
159+ isOverlap.resize (_size,0 );
160+ for ( size_t j=0 ; j < _size; ++j ){
161+ Feature *feat = permFeatures[j];
162+ permTest[j] = metricTest[permutation[j]];
163+ isOverlap[j] = ( feat && !feat->Ignore ()
164+ && feat->getMetricType () == Overlap ) ? 1 : 0 ;
165+ }
155166 }
156167
157168 size_t DistanceTester::test ( const vector<FeatureValue *>& G,
@@ -164,9 +175,15 @@ namespace Timbl{
164175 cerr << " feature " << TrueF << " (perm=" << permutation[TrueF]
165176 << " )" << endl;
166177#endif
167- double result = metricTest[permutation[TrueF]]->test ( (*FV )[TrueF],
168- G[i],
169- permFeatures[TrueF] );
178+ double result;
179+ if ( isOverlap[TrueF] ){
180+ // plain Overlap: distance is 0 for an exact value match, otherwise
181+ // the feature weight -- no virtual metric dispatch needed.
182+ result = ( (*FV )[TrueF] == G[i] ) ? 0.0 : permFeatures[TrueF]->Weight ();
183+ }
184+ else {
185+ result = permTest[TrueF]->test ( (*FV )[TrueF], G[i], permFeatures[TrueF] );
186+ }
170187 distances[i+1 ] = distances[i] + result;
171188 if ( distances[i+1 ] > Threshold ){
172189#ifdef DBGTEST
0 commit comments