|
|
@@ -1490,246 +1490,6 @@ TEST ( functions, Rebalance )
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
-
|
|
|
-// conversion between degrees and radians
|
|
|
-static const double MY_PI = 3.14159265358979323846;
|
|
|
-static const double TO_RADD = MY_PI / 180.0;
|
|
|
-static const double TO_DEGD = 180.0 / MY_PI;
|
|
|
-
|
|
|
-#ifdef __GNUC__
|
|
|
-#pragma GCC diagnostic push
|
|
|
-#pragma GCC diagnostic ignored "-Wunused-function"
|
|
|
-#endif
|
|
|
-
|
|
|
-static inline float GeodistVincenty ( double lat1, double lon1, double lat2, double lon2 )
|
|
|
-{
|
|
|
- lat1 *= TO_RADD;
|
|
|
- lon1 *= TO_RADD;
|
|
|
- lat2 *= TO_RADD;
|
|
|
- lon2 *= TO_RADD;
|
|
|
- const double a = 6378137;
|
|
|
- const double b = 6356752.314245;
|
|
|
- double f = ( a - b ) / a;
|
|
|
- double L = lon2 - lon1;
|
|
|
- double u1 = atan ( ( 1 - f ) * tan ( lat1 ) );
|
|
|
- double u2 = atan ( ( 1 - f ) * tan ( lat2 ) );
|
|
|
- double sin_u1 = sin ( u1 );
|
|
|
- double cos_u1 = cos ( u1 );
|
|
|
- double sin_u2 = sin ( u2 );
|
|
|
- double cos_u2 = cos ( u2 );
|
|
|
- double lambda = L;
|
|
|
- double lambda_pi = 2 * MY_PI;
|
|
|
- double sin_sigma = 0, cos_sigma = 0, sigma = 0, cos_sq_alpha = 0, cos2sigma_m = 0;
|
|
|
- while ( fabs ( lambda - lambda_pi )>1e-12 )
|
|
|
- {
|
|
|
- double sin_lambda = sin ( lambda );
|
|
|
- double cos_lambda = cos ( lambda );
|
|
|
- sin_sigma = sqrt ( ( cos_u2 * sin_lambda ) * ( cos_u2 * sin_lambda ) +
|
|
|
- ( cos_u1 * sin_u2 - sin_u1 * cos_u2 * cos_lambda ) * ( cos_u1 * sin_u2 - sin_u1 * cos_u2 * cos_lambda ) );
|
|
|
- cos_sigma = sin_u1 * sin_u2 + cos_u1 * cos_u2 * cos_lambda;
|
|
|
- sigma = atan2 ( sin_sigma, cos_sigma );
|
|
|
- double alpha = asin ( cos_u1 * cos_u2 * sin_lambda / sin_sigma );
|
|
|
- cos_sq_alpha = cos ( alpha ) * cos ( alpha );
|
|
|
- cos2sigma_m = cos_sigma - 2 * sin_u1 * sin_u2 / cos_sq_alpha;
|
|
|
- double cc = f / 16 * cos_sq_alpha * ( 4 + f * ( 4 - 3 * cos_sq_alpha ) );
|
|
|
- lambda_pi = lambda;
|
|
|
- lambda = L + ( 1 - cc ) * f * sin ( alpha ) *
|
|
|
- ( sigma + cc * sin_sigma * ( cos2sigma_m + cc * cos_sigma * ( -1 + 2 * cos2sigma_m * cos2sigma_m ) ) );
|
|
|
- }
|
|
|
- double usq = cos_sq_alpha * ( a * a - b * b ) / ( b * b );
|
|
|
- double aa = 1 + usq / 16384 * ( 4096 + usq * ( -768 + usq * ( 320 - 175 * usq ) ) );
|
|
|
- double bb = usq / 1024 * ( 256 + usq * ( -128 + usq * ( 74 - 47 * usq ) ) );
|
|
|
- double delta_sigma =
|
|
|
- bb * sin_sigma * ( cos2sigma_m + bb / 4 * ( cos_sigma * ( -1 + 2 * cos2sigma_m * cos2sigma_m ) -
|
|
|
- bb / 6 * cos2sigma_m * ( -3 + 4 * sin_sigma * sin_sigma ) * ( -3 + 4 * cos2sigma_m * cos2sigma_m ) ) );
|
|
|
- double c = b * aa * ( sigma - delta_sigma );
|
|
|
- return ( float ) c;
|
|
|
-}
|
|
|
-
|
|
|
-#ifdef __GNUC__
|
|
|
-#pragma GCC diagnostic pop
|
|
|
-#endif
|
|
|
-
|
|
|
-void DestVincenty ( double lat1, double lon1, double brng, double dist, double * lat2, double * lon2 )
|
|
|
-{
|
|
|
- double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563; // WGS-84 ellipsiod
|
|
|
- double s = dist;
|
|
|
- double alpha1 = brng * TO_RADD;
|
|
|
- double sinAlpha1 = sin ( alpha1 );
|
|
|
- double cosAlpha1 = cos ( alpha1 );
|
|
|
-
|
|
|
- double tanU1 = ( 1 - f ) * tan ( lat1 * TO_RADD );
|
|
|
- double cosU1 = 1 / sqrt ( 1 + tanU1 * tanU1 ), sinU1 = tanU1 * cosU1;
|
|
|
- double sigma1 = atan2 ( tanU1, cosAlpha1 );
|
|
|
- double sinAlpha = cosU1 * sinAlpha1;
|
|
|
- double cosSqAlpha = 1 - sinAlpha * sinAlpha;
|
|
|
- double uSq = cosSqAlpha * ( a * a - b * b ) / ( b * b );
|
|
|
- double A = 1 + uSq / 16384 * ( 4096 + uSq * ( -768 + uSq * ( 320 - 175 * uSq ) ) );
|
|
|
- double B = uSq / 1024 * ( 256 + uSq * ( -128 + uSq * ( 74 - 47 * uSq ) ) );
|
|
|
-
|
|
|
- double sigma = s / ( b * A ), sigmaP = 2 * MY_PI;
|
|
|
- double cos2SigmaM = 0, sinSigma = 0, cosSigma = 0;
|
|
|
- while ( fabs ( sigma - sigmaP )>1e-12 )
|
|
|
- {
|
|
|
- cos2SigmaM = cos ( 2 * sigma1 + sigma );
|
|
|
- sinSigma = sin ( sigma );
|
|
|
- cosSigma = cos ( sigma );
|
|
|
- double deltaSigma = B * sinSigma * ( cos2SigmaM + B / 4 * ( cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) -
|
|
|
- B / 6 * cos2SigmaM * ( -3 + 4 * sinSigma * sinSigma ) * ( -3 + 4 * cos2SigmaM * cos2SigmaM ) ) );
|
|
|
- sigmaP = sigma;
|
|
|
- sigma = s / ( b * A ) + deltaSigma;
|
|
|
- }
|
|
|
-
|
|
|
- double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
|
|
|
- *lat2 = atan2 ( sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
|
|
|
- ( 1 - f ) * sqrt ( sinAlpha * sinAlpha + tmp * tmp ) );
|
|
|
- double lambda = atan2 ( sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1 );
|
|
|
- double C = f / 16 * cosSqAlpha * ( 4 + f * ( 4 - 3 * cosSqAlpha ) );
|
|
|
- double L = lambda - ( 1 - C ) * f * sinAlpha *
|
|
|
- ( sigma + C * sinSigma * ( cos2SigmaM + C * cosSigma * ( -1 + 2 * cos2SigmaM * cos2SigmaM ) ) );
|
|
|
- *lon2 = ( lon1 * TO_RADD + L + 3 * MY_PI );
|
|
|
- while ( *lon2>2 * MY_PI )
|
|
|
- *lon2 -= 2 * MY_PI;
|
|
|
- *lon2 -= MY_PI;
|
|
|
- *lat2 *= TO_DEGD;
|
|
|
- *lon2 *= TO_DEGD;
|
|
|
-}
|
|
|
-
|
|
|
-static const int NFUNCS = 3;
|
|
|
-
|
|
|
-float CalcGeofunc ( int iFunc, double * t )
|
|
|
-{
|
|
|
- switch ( iFunc )
|
|
|
- {
|
|
|
- case 0: return GeodistSphereDeg ( float(t[0]), float(t[1]), float(t[2]), float(t[3]) ); break;
|
|
|
- case 1: return GeodistAdaptiveDeg ( float(t[0]), float(t[1]), float(t[2]), float(t[3]) ); break;
|
|
|
- case 2: return GeodistFlatDeg ( float(t[0]), float(t[1]), float(t[2]), float(t[3]) ); break;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_geodist )
|
|
|
-{
|
|
|
- CSphVector<double> dBench;
|
|
|
- for ( int adist = 10; adist<=10 * 1000 * 1000; adist *= 10 )
|
|
|
- for ( int dist = adist; dist<10 * adist && dist<20 * 1000 * 1000; dist += 2 * adist )
|
|
|
- {
|
|
|
- double avgerr[NFUNCS] = { 0 }, maxerr[NFUNCS] = { 0 };
|
|
|
- int n = 0;
|
|
|
- for ( int lat = -80; lat<=80; lat += 10 )
|
|
|
- {
|
|
|
- for ( int lon = -179; lon<180; lon += 3 )
|
|
|
- {
|
|
|
- for ( int b = 0; b<360; b += 3, n++ )
|
|
|
- {
|
|
|
- double t[4] = { double ( lat ), double ( lon ), 0, 0 };
|
|
|
- DestVincenty ( t[0], t[1], b, dist, t + 2, t + 3 );
|
|
|
- for ( int j = 0; j<4; j++ )
|
|
|
- dBench.Add ( t[j] );
|
|
|
- for ( int f = 0; f<NFUNCS; f++ )
|
|
|
- {
|
|
|
- float fDist = CalcGeofunc ( f, t );
|
|
|
- double err = fabs ( 100 * ( double ( fDist ) - double ( dist ) )
|
|
|
- / double ( dist ) ); // relative error, in percents
|
|
|
- avgerr[f] += err;
|
|
|
- maxerr[f] = Max ( err, maxerr[f] );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if ( dist>=1000 )
|
|
|
- printf ( "%5dkm", dist / 1000 );
|
|
|
- else
|
|
|
- printf ( "%6dm", dist );
|
|
|
- for ( int f = 0; f<NFUNCS; f++ )
|
|
|
- printf ( ", f%d %5.2f%% %5.2f%%", f, avgerr[f] / n, maxerr[f] );
|
|
|
- printf ( "\n" );
|
|
|
- }
|
|
|
-
|
|
|
- const int RUNS = 10;
|
|
|
- float fDist = 0;
|
|
|
- double * tmax = dBench.Begin () + dBench.GetLength ();
|
|
|
- int64_t tm;
|
|
|
- printf ( "%d calls in bench\n", RUNS * dBench.GetLength () );
|
|
|
-
|
|
|
- tm = sphMicroTimer ();
|
|
|
- for ( int r = 0; r<RUNS; r++ )
|
|
|
- for ( double * t = dBench.Begin (); t<tmax; t += 4 )
|
|
|
- fDist += GeodistSphereDeg ( float ( t[0] ), float ( t[1] ), float ( t[2] ), float ( t[3] ) );
|
|
|
- printf ( INT64_FMT" us sphere\n", sphMicroTimer () - tm );
|
|
|
-
|
|
|
- tm = sphMicroTimer ();
|
|
|
- for ( int r = 0; r<RUNS; r++ )
|
|
|
- for ( double * t = dBench.Begin (); t<tmax; t += 4 )
|
|
|
- fDist += GeodistFlatDeg ( float ( t[0] ), float ( t[1] ), float ( t[2] ), float ( t[3] ) );
|
|
|
- printf ( INT64_FMT" us flat\n", sphMicroTimer () - tm );
|
|
|
-
|
|
|
- tm = sphMicroTimer ();
|
|
|
- for ( int r = 0; r<RUNS; r++ )
|
|
|
- for ( double * t = dBench.Begin (); t<tmax; t += 4 )
|
|
|
- fDist += GeodistAdaptiveDeg ( float ( t[0] ), float ( t[1] ), float ( t[2] ), float ( t[3] ) );
|
|
|
- printf ( INT64_FMT" us adaptive\n", sphMicroTimer () - tm );
|
|
|
-
|
|
|
- printf ( "res %f\n", fDist );
|
|
|
-
|
|
|
- // coordinates from Wikimapia/Googlemaps
|
|
|
- //
|
|
|
- // distances by Wolfram Alpha (supposedly defaults to Vincenty method)
|
|
|
- // geodistance[{51.5007788, -0.1246771}, {46.2041222, 6.1524349}]
|
|
|
- //
|
|
|
- // 40.6890895, -74.0446899 center of the torch of the Statue of Liberty, New York, USA
|
|
|
- // 40.7041146, -74.0152399 center of The Sphere in Battery Park, New York, USA
|
|
|
- // 40.7643929, -73.9997683 tip of Lockheed A-12 (SR-71) on Intrepid, NY, USA
|
|
|
- // 40.7642578, -73.9994565 tail of Lockheed A-12 (SR-71) on Intrepid, NY, USA
|
|
|
- // 55.7535204, 37.6195371 center of Senatskaya tower, Red Square, Moscow, Russia
|
|
|
- // 51.6606654, 39.1999751 center of Lenin statue, Lenin Square, Voronezh, Russia
|
|
|
- // 49.2055275, -123.2014474 NW corner of Runway 08L-26R, YVR airport, Vancouver, Canada
|
|
|
- // 49.2007563, -123.1596478 NE corner of Runway 08L-26R, YVR airport, Vancouver, Canada
|
|
|
- // 37.6284983, -122.3927365 N corner of L on Runway 10L-28R, SFO airport, San Francisco, USA
|
|
|
- // 37.6137799, -122.3577954 S corner of R on Runway 10L-28R, SFO airport, San Francisco, USA
|
|
|
- // 68.974714, 33.0611873 tip of Lenin icebreaker, Murmansk, Russia
|
|
|
- // -22.9519125, -43.2105616 center of the head of Christ the Redeemer statue, Rio de Janeiro, Brazil
|
|
|
- // 51.5007788, -0.1246771 tip of Big Ben tower, London, England
|
|
|
- // 29.97973, 31.1342695 tip of Pyramid of Cheops, Cairo, Egypt
|
|
|
- // 41.4034549, 2.1741718 tip of the southern tower of Sagrada Familia, Barcelona, Spain
|
|
|
- // 42.6848586, 23.3188623 tip of National Palace of Culture, Sofia, Bulgaria
|
|
|
- // 46.2041222, 6.1524349 center of the fountain in English garden, Geneva, Switzerland
|
|
|
- // 37.8106517, -122.4174678 tip of SS Jeremiah O'Brien, Pier 45, San Francisco, USA
|
|
|
- // 37.8114358, -122.4186279 tail of SS Jeremiah O'Brien, Pier 45, San Francisco, USA
|
|
|
- // 64.1475975, -21.9224185 center of Sun Voyager in Reykjavik, Iceland
|
|
|
- // 63.8079982, -19.5589042 center of Eyjafjallajokull volcano, Iceland
|
|
|
- double dTest[][5] =
|
|
|
- {
|
|
|
- { 40.7643929, -73.9997683, 40.7642578, -73.9994565, 30.3013 }, // Lockheed A-12 (SR-71) length (30.97m per wiki)
|
|
|
- { 37.8106517, -122.4174678, 37.8114358, -122.4186279, 134.20 }, // SS Jeremiah O'Brien length ((134.57m per wiki)
|
|
|
- { 40.6890895, -74.0446899, 40.7041146, -74.0152399, 2996.59 }, // Statue of Liberty to The Sphere
|
|
|
- { 49.2055275, -123.2014474, 49.2007563, -123.1596478, 3091.96 }, // YVR Runway 08L-26R length (3030m per wiki)
|
|
|
- { 37.6284983, -122.3927365, 37.6137799, -122.3577954, 3490.54 }, // SFO Runway 10L-28R length (3618m per wiki)
|
|
|
- { 64.1475975, -21.9224185, 63.8079982, -19.5589042, 121768.14 }, // Reykjavik to Eyjafjallajokull
|
|
|
- { 55.7535204, 37.6195371, 51.6606654, 39.1999751, 467301.55 }, // Moscow to Voronezh
|
|
|
- { 51.5007788, -0.1246771, 46.2041222, 6.1524349, 747189.88 }, // London to Geneva
|
|
|
- { 51.5007788, -0.1246771, 41.4034549, 2.1741718, 1136075.00 }, // London to Barcelona
|
|
|
- { 51.5007788, -0.1246771, 42.6848586, 23.3188623, 2019138.10 }, // London to Sofia
|
|
|
- { 51.5007788, -0.1246771, 29.97973, 31.1342695, 3513002.04 }, // London to Cairo
|
|
|
- { 68.974714, 33.0611873, -22.9519125, -43.2105616, 11833803.11 }, // Murmansk to Rio
|
|
|
- { 0, 0, 0.5, 179.5, 19936288.579 }, // antipodes, direct Vincenty killer
|
|
|
- // { 0, 0, 0.5, 179.7, 19944127.421 }, // antipodes, inverse Vincenty killer
|
|
|
- };
|
|
|
-
|
|
|
- for ( int i=0; i<int(sizeof(dTest)/sizeof(dTest[0])); i++ )
|
|
|
- {
|
|
|
- double * t = dTest[i];
|
|
|
- printf ( "%2d: ref %10.1f", i, t[4] );
|
|
|
- for ( int iFunc=0; iFunc<NFUNCS; iFunc++ )
|
|
|
- {
|
|
|
- float fDist = CalcGeofunc ( iFunc, t );
|
|
|
- printf ( ", f%d %5.2f%%", iFunc, 100*(fDist-t[4])/t[4] );
|
|
|
- }
|
|
|
- printf ( "\n" );
|
|
|
- }
|
|
|
- printf ( "\n" );
|
|
|
-}
|
|
|
-
|
|
|
// parsing size - number with possible suffixes k, m, g, t.
|
|
|
TEST (functions, size_parser)
|
|
|
{
|
|
|
@@ -2006,274 +1766,6 @@ TEST ( functions, FindLastNumeric )
|
|
|
static const char * sNum3 = "12 34";
|
|
|
ASSERT_EQ ( sNum3 + 3, sphFindLastNumeric ( sNum3, 5 ) );
|
|
|
}
|
|
|
-const char* sPattern="DeadBeefDeadBeefDeadBeefDeadBeefDeadBeefDeadBeefDeadBeefDeadBeef";
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_bench_allocator_linear )
|
|
|
-{
|
|
|
- static const DWORD uTries = 10000000;
|
|
|
-
|
|
|
- struct chunk_t {
|
|
|
- BYTE * pChunk;
|
|
|
- BYTE uSize;
|
|
|
- };
|
|
|
-
|
|
|
- CSphVector<chunk_t> dChunks;
|
|
|
- dChunks.Resize (uTries);
|
|
|
- auto iTimeSpan = -sphMicroTimer ();
|
|
|
- BYTE iAllocate = 1;
|
|
|
- for ( auto & chunk : dChunks)
|
|
|
- {
|
|
|
- chunk.uSize = iAllocate;
|
|
|
- chunk.pChunk = sphAllocateSmall ( iAllocate );
|
|
|
- memcpy ( chunk.pChunk, sPattern, iAllocate );
|
|
|
- ++iAllocate;
|
|
|
- if ( iAllocate > MAX_SMALL_OBJECT_SIZE )
|
|
|
- iAllocate = 1;
|
|
|
- }
|
|
|
- for ( auto &chunk : dChunks )
|
|
|
- sphDeallocateSmall (chunk.pChunk, chunk.uSize);
|
|
|
- iTimeSpan += sphMicroTimer();
|
|
|
- auto uReserved = sphGetSmallReservedSize ();
|
|
|
- std::cout << "Took " << iTimeSpan << " uSec, reserved " << uReserved << " bytes.\n";
|
|
|
- ASSERT_EQ ( sphGetSmallAllocatedSize (), 0 );
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_bench_allocator_linear64 )
|
|
|
-{
|
|
|
- static const DWORD uTries = 1000;
|
|
|
-
|
|
|
- struct chunk_t
|
|
|
- {
|
|
|
- BYTE * pChunk;
|
|
|
- BYTE uSize;
|
|
|
- };
|
|
|
-
|
|
|
- CSphVector<chunk_t> dChunks;
|
|
|
- dChunks.Resize ( uTries );
|
|
|
- auto iTimeSpan = -sphMicroTimer ();
|
|
|
- BYTE iAllocate = 64;
|
|
|
- for ( auto &chunk : dChunks )
|
|
|
- {
|
|
|
- chunk.uSize = iAllocate;
|
|
|
- chunk.pChunk = sphAllocateSmall ( iAllocate );
|
|
|
- memcpy ( chunk.pChunk, sPattern, iAllocate );
|
|
|
-// iAllocate++;
|
|
|
- if ( iAllocate>MAX_SMALL_OBJECT_SIZE )
|
|
|
- iAllocate = 1;
|
|
|
- }
|
|
|
- for ( auto &chunk : dChunks )
|
|
|
- sphDeallocateSmall ( chunk.pChunk, chunk.uSize );
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- auto uReserved = sphGetSmallReservedSize ();
|
|
|
- std::cout << "Took " << iTimeSpan << " uSec, reserved " << uReserved << " bytes.\n";
|
|
|
- ASSERT_EQ ( sphGetSmallAllocatedSize (), 0 );
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_bench_allocator_small )
|
|
|
-{
|
|
|
- static const DWORD uTries = 10000000;
|
|
|
- static const DWORD uLoops = uTries/MAX_SMALL_OBJECT_SIZE;
|
|
|
-
|
|
|
- CSphVector<BYTE*> dChunks;
|
|
|
- dChunks.Resize ( MAX_SMALL_OBJECT_SIZE );
|
|
|
- auto iTimeSpan = -sphMicroTimer ();
|
|
|
-
|
|
|
- for ( DWORD j=0; j<uLoops; ++j)
|
|
|
- {
|
|
|
- ARRAY_FOREACH ( i, dChunks )
|
|
|
- {
|
|
|
- dChunks[i] = sphAllocateSmall ( MAX_SMALL_OBJECT_SIZE - i );
|
|
|
- memcpy ( dChunks[i], sPattern, MAX_SMALL_OBJECT_SIZE - i );
|
|
|
- }
|
|
|
-
|
|
|
- ARRAY_FOREACH ( i, dChunks )
|
|
|
- sphDeallocateSmall ( dChunks[i], MAX_SMALL_OBJECT_SIZE - i );
|
|
|
- }
|
|
|
-
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- auto uReserved = sphGetSmallReservedSize ();
|
|
|
- std::cout << uLoops << " loops took " << iTimeSpan << " uSec, reserved " << uReserved << " bytes.\n";
|
|
|
- ASSERT_EQ ( sphGetSmallAllocatedSize (), 0 );
|
|
|
-}
|
|
|
-
|
|
|
-// benches for EscapeJsonString_t
|
|
|
-inline static bool IsEscapeChar1 ( char c )
|
|
|
-{
|
|
|
- return memchr ( "\"\\\b\f\n\r\t", c, 8 )!=nullptr; // \ is \x5C, " is \x22
|
|
|
-}
|
|
|
-
|
|
|
-inline static bool IsEscapeChar2 ( char c )
|
|
|
-{
|
|
|
- return strchr ( "\"\\\b\f\n\r\t", c )!=nullptr; // \ is \x5C, " is \x22
|
|
|
-}
|
|
|
-
|
|
|
-inline static bool IsEscapeChar3 ( char c )
|
|
|
-{
|
|
|
- switch ( c )
|
|
|
- {
|
|
|
- case '\b': case '\f': case '\n': case '\r': case '\t': case '\"': case '\\' : return true;
|
|
|
- default: return false;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-inline static bool IsEscapeChar4 ( char c ) // winner!
|
|
|
-{
|
|
|
- alignas ( 128 ) static const bool lookup[] =
|
|
|
- {0,0,0,0,0,0,0,0, 1,1,1,0,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
|
|
- 0,0,1,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
|
|
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,
|
|
|
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
|
|
- };
|
|
|
- return ( c & 0x80 ) ? false : lookup[(BYTE)c];
|
|
|
-}
|
|
|
-
|
|
|
-/* gcc/clang only
|
|
|
-inline static bool IsEscapeChar6 ( char c )
|
|
|
-{
|
|
|
- // 0x1000 0x400003700
|
|
|
- static const __uint128_t uLookupMask = ( (__uint128_t) 0x1000 << 64 ) | 0x400003700;
|
|
|
- return ( c & 0x80 ) ? false : uLookupMask & ( (__uint128_t) 1 << c );
|
|
|
-}
|
|
|
-*/
|
|
|
-
|
|
|
-inline static char GetEscapedChar1 ( char c )
|
|
|
-{
|
|
|
- switch ( c )
|
|
|
- {
|
|
|
- case '\b': return 'b'; // \x08
|
|
|
- case '\t': return 't'; // \x09
|
|
|
- case '\n': return 'n'; // \x0A
|
|
|
- case '\f': return 'f'; // \x0C
|
|
|
- case '\r': return 'r'; // \x0D
|
|
|
-
|
|
|
- default: return c;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-inline static char GetEscapedChar2 ( char c ) // winner!
|
|
|
-{
|
|
|
- alignas ( 16 ) static const char dTransform[16] = {'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
|
|
- 'b', 't', 'n', '\x0B', 'f', 'r', '\x0E', '\x0F' };
|
|
|
- //return dTransform[(BYTE) c];
|
|
|
- return ( c & 0xF0 ) ? c : dTransform[(BYTE) c];
|
|
|
-}
|
|
|
-
|
|
|
-alignas ( 128 ) static const BYTE g_Transform[] =
|
|
|
- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 'b'|0x80, 't'|0x80, 'n'|0x80, 0x0b, 'f'|0x80, 'r'|0x80, 0x0e, 0x0f,
|
|
|
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
|
|
|
- 0x20,0x21,'\"'|0x80,0x23,0x24,0x25,0x26,0x27, 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
|
|
|
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
|
|
|
- 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
|
|
|
- 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, 0x58,0x59,0x5a,0x5b,'\\'|0x80,0x5d,0x5e,0x5f,
|
|
|
- 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67, 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
|
|
- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
|
|
|
- };
|
|
|
-
|
|
|
-inline static bool IsEscapeChar5 ( char c )
|
|
|
-{
|
|
|
- return ( c & 0x80 ) ? false : g_Transform[(BYTE) c] & 0x80;
|
|
|
-}
|
|
|
-
|
|
|
-inline static char GetEscapedChar3 ( char c )
|
|
|
-{
|
|
|
- return ( c & 0x80 ) ? c : g_Transform[(BYTE) c]&0x7F;
|
|
|
-}
|
|
|
-
|
|
|
-// here IsEscapeChar5 already excluded bytes with high bit set, so even simpler!
|
|
|
-inline static char GetEscapedChar3combo ( char c )
|
|
|
-{
|
|
|
- return g_Transform[(BYTE) c] & 0x7F;
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, is_get_escaped_integrity )
|
|
|
-{
|
|
|
- for ( int i=1; i<255; ++i)
|
|
|
- {
|
|
|
- auto bRefCheck = IsEscapeChar2 ( i );
|
|
|
- auto cRefCheck = GetEscapedChar1 ( i );
|
|
|
- ASSERT_EQ ( bRefCheck, IsEscapeChar1 ( i ) ) << i;
|
|
|
- ASSERT_EQ ( bRefCheck, IsEscapeChar3 ( i ) ) << i;
|
|
|
- ASSERT_EQ ( bRefCheck, IsEscapeChar4 ( i ) ) << i << char(i);
|
|
|
- ASSERT_EQ ( bRefCheck, IsEscapeChar5 ( i ) ) << i;
|
|
|
- ASSERT_EQ ( cRefCheck, GetEscapedChar2 ( i ) ) << i;
|
|
|
- ASSERT_EQ ( cRefCheck, GetEscapedChar3 ( i ) ) << i;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_bench_strchr )
|
|
|
-{
|
|
|
- static const DWORD uTries = 100000000;
|
|
|
-
|
|
|
- CSphVector<char> dChars;
|
|
|
- int64_t tmTimes[16];
|
|
|
- auto pTime = &tmTimes[0];
|
|
|
-
|
|
|
- dChars.Resize (128);
|
|
|
- for ( char& c : dChars )
|
|
|
- c = sphRand() & 0xFF;
|
|
|
-
|
|
|
- bool bRes = false;
|
|
|
-
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= !!dChars[i & 0x7F];
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= !!dChars[i & 0x7F];
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer (); // control empty pass
|
|
|
- for ( DWORD i=0; i<uTries; ++i)
|
|
|
- bRes |= IsEscapeChar1 ( dChars[i & 0x7F] ); // memchr
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= IsEscapeChar2 ( dChars[i & 0x7F] ); // strchr
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= IsEscapeChar3 ( dChars[i & 0x7F] ); // switch
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= IsEscapeChar4 ( dChars[i & 0x7F] ); // lookup bool
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= !!GetEscapedChar1( dChars[i & 0x7F] ); // get switch
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= !!GetEscapedChar2( dChars[i & 0x7F] ); // short lookup
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= IsEscapeChar5 ( dChars[i & 0x7F] ); // common lookup
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- bRes |= !!GetEscapedChar3( dChars[i & 0x7F] ); // common lookup get
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- if ( IsEscapeChar2 ( dChars[i & 0x7F] ) ) // combo usual
|
|
|
- bRes |= !!GetEscapedChar1 ( dChars[i & 0x7F] );
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
- for ( DWORD i = 0; i<uTries; ++i )
|
|
|
- if ( IsEscapeChar5 ( dChars[i & 0x7F] ) ) // combo common
|
|
|
- bRes |= !!GetEscapedChar3combo ( dChars[i & 0x7F] );
|
|
|
-
|
|
|
- *pTime++ = sphMicroTimer ();
|
|
|
-
|
|
|
- auto iRef = tmTimes[1]-tmTimes[0]; // reference time of empty loop
|
|
|
- std::cout << "Took\n"
|
|
|
- "rf:" << iRef << "\n-------\n";
|
|
|
- for ( auto pTm = &tmTimes[1]; pTm<pTime-1; ++pTm )
|
|
|
- std::cout << pTm-&tmTimes[0] << ": " << pTm[1]-pTm[0]-iRef << "\n";
|
|
|
-
|
|
|
- std::cout << bRes << "\n";
|
|
|
- ASSERT_TRUE ( bRes );
|
|
|
-}
|
|
|
|
|
|
TEST ( functions, UItoA_ItoA )
|
|
|
{
|
|
|
@@ -2692,93 +2184,6 @@ TEST ( functions, sph_Sprintf_fractimezero )
|
|
|
sBuf.Clear ();
|
|
|
}
|
|
|
|
|
|
-TEST ( functions, DISABLED_bench_Sprintf )
|
|
|
-{
|
|
|
- char sBuf[40];
|
|
|
- auto uLoops = 10000000;
|
|
|
-
|
|
|
- auto iTimeSpan = -sphMicroTimer ();
|
|
|
- for ( auto i=0; i<uLoops; ++i )
|
|
|
- sph::Sprintf ( sBuf, "%d", 1000000 );
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- std::cout << "\n" << uLoops << " of sph::sprintf took " << iTimeSpan << " uSec";
|
|
|
-
|
|
|
- iTimeSpan = -sphMicroTimer ();
|
|
|
- for ( auto i = 0; i<uLoops; ++i )
|
|
|
- sprintf ( sBuf, "%d", 1000000 );
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- std::cout << "\n" << uLoops << " of sprintf took " << iTimeSpan << " uSec\n";
|
|
|
-
|
|
|
- ASSERT_EQ ( sphGetSmallAllocatedSize (), 0 );
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_bench_builder_Appendf_vs_Sprintf )
|
|
|
-{
|
|
|
- auto uLoops = 1000000;
|
|
|
-
|
|
|
- const char * sFieldFmt = R"({"field":%d, "lcs":%u, "hit_count":%u, "word_count":%u, "tf_idf":%d, "min_idf":%d, )"
|
|
|
- R"("max_idf":%d, "sum_idf":%d, "min_hit_pos":%d, "min_best_span_pos":%d, "exact_hit":%u, )"
|
|
|
- R"("max_window_hits":%d, "min_gaps":%d, "exact_order":%u, "lccs":%d, "wlccs":%f, "atc":%f})";
|
|
|
-
|
|
|
- StringBuilder_c sBuf;
|
|
|
-
|
|
|
- auto iTimeSpan = -sphMicroTimer ();
|
|
|
- for ( auto i = 0; i<uLoops; ++i )
|
|
|
- {
|
|
|
- sBuf.Appendf ( sFieldFmt, 3, 23, 23465, 234, 234, 4346,
|
|
|
- 345345, 3434535, 345, 54, 1,
|
|
|
- 23, 5, 0, 34, .345f, .234f );
|
|
|
- sBuf.Clear();
|
|
|
- }
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- std::cout << "\n" << uLoops << " of Appendf took " << iTimeSpan << " uSec";
|
|
|
-
|
|
|
- iTimeSpan = -sphMicroTimer ();
|
|
|
- for ( auto i = 0; i<uLoops; ++i )
|
|
|
- {
|
|
|
- sBuf.Sprintf ( sFieldFmt, 3, 23, 23465, 234, 234, 4346,
|
|
|
- 345345, 3434535, 345, 54, 1,
|
|
|
- 23, 5, 0, 34, .345f, .234f );
|
|
|
- sBuf.Clear();
|
|
|
- }
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- std::cout << "\n" << uLoops << " of Sprintf took " << iTimeSpan << " uSec\n";
|
|
|
-
|
|
|
- ASSERT_EQ ( sphGetSmallAllocatedSize (), 0 );
|
|
|
-}
|
|
|
-
|
|
|
-TEST ( functions, DISABLED_bench_builder_Appendf_vs_Sprintf_ints )
|
|
|
-{
|
|
|
- auto uLoops = 1000000;
|
|
|
-
|
|
|
- const char * sFieldFmt = R"({"field":%d, "lcs":%u, "hit_count":%u, "word_count":%u, "tf_idf":%d, "min_idf":%d, )"
|
|
|
- R"("max_idf":%d, "sum_idf":%d, "min_hit_pos":%d, "min_best_span_pos":%d, "exact_hit":%u, )"
|
|
|
- R"("max_window_hits":%d, "min_gaps":%d, "exact_order":%u, "lccs":%d, "wlccs":%d, "atc":%d})";
|
|
|
-
|
|
|
- StringBuilder_c sBuf;
|
|
|
-
|
|
|
- auto iTimeSpan = -sphMicroTimer ();
|
|
|
- for ( auto i = 0; i<uLoops; ++i )
|
|
|
- {
|
|
|
- sBuf.Appendf ( sFieldFmt, 3, 23, 23465, 234, 234, 4346, 345345, 3434535, 345, 54, 1, 23, 5, 0, 34, 45
|
|
|
- , 234 );
|
|
|
- sBuf.Clear ();
|
|
|
- }
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- std::cout << "\n" << uLoops << " of Appendf took " << iTimeSpan << " uSec";
|
|
|
-
|
|
|
- iTimeSpan = -sphMicroTimer ();
|
|
|
- for ( auto i = 0; i<uLoops; ++i )
|
|
|
- {
|
|
|
- sBuf.Sprintf ( sFieldFmt, 3, 23, 23465, 234, 234, 4346, 345345, 3434535, 345, 54, 1, 23, 5, 0, 34, 45
|
|
|
- , 234 );
|
|
|
- sBuf.Clear ();
|
|
|
- }
|
|
|
- iTimeSpan += sphMicroTimer ();
|
|
|
- std::cout << "\n" << uLoops << " of Sprintf took " << iTimeSpan << " uSec\n";
|
|
|
-
|
|
|
- ASSERT_EQ ( sphGetSmallAllocatedSize (), 0 );
|
|
|
-}
|
|
|
|
|
|
TEST ( functions, VectorEx )
|
|
|
{
|