1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0029399: Optimize reading of floating point values from text strings

Function Strtod() is reimplemented using open source (MIT-style license) code by David M. Gay instead of strtod() provided by standard run-time library. This improves its performance by 3-10 times.

Functions Atof(), Strtod(), Printf(), Sprintf(), Fprintf() are declared as extern "C" to be usable from C programs.

Strtod() is used in Interface_FileReaderData::Fastof() and in RWStl_Reader to accelerate their work.

DRAW command QATestAtof and test perf fclasses strtod are added to check correctness and performance of Strtod().
Test perf draw restore is added to monitor performance of reading BREP files.

Minor off-topic corrections:
- method Standard_GUID::Assign (const Standard_UUID&) is implemented (was empty);
- Precision.hxx is included in BRepMesh_Vertex.hxx that uses it.
This commit is contained in:
abv
2017-12-24 09:44:04 +03:00
committed by apn
parent 0edbf10564
commit 07bbde451a
16 changed files with 481 additions and 362 deletions

View File

@@ -79,9 +79,9 @@ Standard_Real.hxx
Standard_ShortReal.cxx
Standard_ShortReal.hxx
Standard_Size.hxx
Standard_SStream.cxx
Standard_SStream.hxx
Standard_Stream.hxx
Standard_Strtod.cxx
Standard_ThreadId.hxx
Standard_Time.hxx
Standard_TooManyUsers.hxx
@@ -92,7 +92,6 @@ Standard_Type.hxx
Standard_TypeDef.hxx
Standard_TypeMismatch.hxx
Standard_Underflow.hxx
Standard_UUID.cxx
Standard_UUID.hxx
Standard_values.h
Standard_Version.hxx

View File

@@ -90,10 +90,12 @@ Standard_Integer HashCodes (const Standard_CString Value,
#define vfprintf_l(theFile, theLocale, theFormat, theArgPtr) vfprintf(theFile, theFormat, theArgPtr)
#endif
/*
double Strtod (const char* theStr, char** theNextPtr)
{
return strtod_l (theStr, theNextPtr, Standard_CLocaleSentry::GetCLocale());
}
*/
double Atof (const char* theStr)
{

View File

@@ -17,73 +17,65 @@
#ifndef _Standard_CString_HeaderFile
# define _Standard_CString_HeaderFile
# ifndef _Standard_TypeDef_HeaderFile
# include <Standard_TypeDef.hxx>
# endif
#include <Standard_Macro.hxx>
# include <string.h>
# include <stdio.h>
# if defined(_MSC_VER) && ! defined(strcasecmp)
# define strcasecmp _stricmp
# endif
# include <string.h>
# include <stdio.h>
// C++ only definitions
#ifdef __cplusplus
# ifndef _Standard_Integer_HeaderFile
# include <Standard_Integer.hxx>
# endif
#include <Standard_Integer.hxx>
__Standard_API Standard_Integer HashCode (const Standard_CString,
const Standard_Integer);
inline Standard_Integer HashCode (const Standard_CString,
const Standard_Integer,
const Standard_Integer);
inline Standard_Integer HashCode (const Standard_CString,
const Standard_Integer ,
const Standard_Integer ,
Standard_Integer& );
__Standard_API Standard_Integer HashCodes (const Standard_CString,
const Standard_Integer);
//! Returns bounded hash code for a null-terminated string, in range [1, theUpper]
__Standard_API Standard_Integer HashCode (const Standard_CString theStr, const Standard_Integer theUpper);
//! Equivalents of functions from standard C library that use always C locale
__Standard_API double Atof (const char* theStr);
__Standard_API double Strtod (const char* theStr, char** theNextPtr);
__Standard_API int Printf (const char* theFormat, ...);
__Standard_API int Fprintf (FILE* theFile, const char* theFormat, ...);
__Standard_API int Sprintf (char* theBuffer, const char* theFormat, ...);
//! Returns 32-bit hash code for the first theLen characters in the string theStr
__Standard_API Standard_Integer HashCodes (const Standard_CString theStr, const Standard_Integer theLen);
//============================================================================
//==== IsEqual : Returns Standard_True if two booleans have the same value
//============================================================================
inline Standard_Boolean IsEqual(const Standard_CString One
,const Standard_CString Two)
{
return (strcmp(One,Two) == 0);
}
//============================================================================
//==== HashCode of CString. Returns the HashCode itself and
//==== the HashCode % Upper
//============================================================================
inline Standard_Integer HashCode (const Standard_CString Value,
const Standard_Integer Len ,
const Standard_Integer Upper ,
Standard_Integer& aHashCode )
{
aHashCode = HashCodes( Value , Len );
// return (Abs( aHashCode ) % Upper ) + 1 ;
return HashCode( (Standard_Integer)aHashCode , Upper ) ;
}
//============================================================================
//==== HashCode of CString. Returns the HashCode itself and
//==== the HashCode % Upper
//============================================================================
inline Standard_Integer HashCode (const Standard_CString Value,
const Standard_Integer Len ,
const Standard_Integer Upper )
//! Returns bounded hash code for the first theLen characters in
//! the string theStr, in range [1, theUpper]
inline Standard_Integer HashCode (const Standard_CString theStr,
const Standard_Integer theLen,
const Standard_Integer theUpper)
{
// return (Abs( HashCodes( Value , Len ) ) % Upper ) + 1 ;
return HashCode( (Standard_Integer) HashCodes( Value , Len ) , Upper ) ;
return HashCode (HashCodes (theStr, theLen), theUpper);
}
//! Returns Standard_True if two strings are equal
inline Standard_Boolean IsEqual (const Standard_CString theOne, const Standard_CString theTwo)
{
return strcmp (theOne, theTwo) == 0;
}
#endif /* __cplusplus */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
//! Equivalent of standard C function atof() that always uses C locale
__Standard_API double Atof (const char* theStr);
//! Optimized equivalent of standard C function strtod() that always uses C locale
__Standard_API double Strtod (const char* theStr, char** theNextPtr);
//! Equivalent of standard C function printf() that always uses C locale
__Standard_API int Printf (const char* theFormat, ...);
//! Equivalent of standard C function fprintf() that always uses C locale
__Standard_API int Fprintf (FILE* theFile, const char* theFormat, ...);
//! Equivalent of standard C function sprintf() that always uses C locale
__Standard_API int Sprintf (char* theBuffer, const char* theFormat, ...);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

View File

@@ -271,18 +271,24 @@ Standard_GUID::Standard_GUID(const Standard_GUID& aGuid)
my8b5 = aGuid.my8b5;
my8b6 = aGuid.my8b6;
}
Standard_GUID::Standard_GUID(const Standard_UUID& aWntGuid)
Standard_GUID::Standard_GUID (const Standard_UUID& theUUID)
{
my32b = aWntGuid.Data1;
my16b1 = aWntGuid.Data2;
my16b2 = aWntGuid.Data3;
my16b3 = (aWntGuid.Data4[0] << 8) | (aWntGuid.Data4[1]) ;
my8b1 = aWntGuid.Data4[2] ;
my8b2 = aWntGuid.Data4[3] ;
my8b3 = aWntGuid.Data4[4] ;
my8b4 = aWntGuid.Data4[5] ;
my8b5 = aWntGuid.Data4[6] ;
my8b6 = aWntGuid.Data4[7] ;
Assign (theUUID);
}
void Standard_GUID::Assign (const Standard_UUID& theUUID)
{
my32b = theUUID.Data1;
my16b1 = theUUID.Data2;
my16b2 = theUUID.Data3;
my16b3 = (theUUID.Data4[0] << 8) | (theUUID.Data4[1]);
my8b1 = theUUID.Data4[2];
my8b2 = theUUID.Data4[3];
my8b3 = theUUID.Data4[4];
my8b4 = theUUID.Data4[5];
my8b5 = theUUID.Data4[6];
my8b6 = theUUID.Data4[7];
}
//=======================================================================

View File

@@ -1,13 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

View File

@@ -17,6 +17,27 @@
*
***************************************************************/
/*
This code has been downloaded from http://www.netlib.org/fp/ on 2017-12-16
and adapted for use within Open CASCADE Technology as follows:
1. Macro IEEE_8087 is defined unconditionally
2. Forward declarations of strtod() and atof(), and 'extern C' statements are commented out
3. strtod() is renamed to Strtod() (OCCT signature)
4. dtoa(), freedtoa() and supporting functions are disabled (see DISABLE_DTOA)
5. Compiler warnings are suppressed
*/
#include <Standard_CString.hxx>
#define IEEE_8087 1
#define DISABLE_DTOA
#ifdef _MSC_VER
#pragma warning(disable: 4706 4244 4127 4334)
#endif
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
@@ -339,7 +360,7 @@ static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
#endif
#ifdef __cplusplus
extern "C" {
//extern "C" {
#endif
#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
@@ -1051,7 +1072,39 @@ typedef struct BF96 { /* Normalized 96-bit software floating point numbers */
{ 0xfcf62c1d, 0xee382c42, 0x46729e03, 1073 },
{ 0x9e19db92, 0xb4e31ba9, 0x6c07a2c2, 1077 }
};
static short int Lhint[2098] = {
static ULLong pfive[27] = {
5ll,
25ll,
125ll,
625ll,
3125ll,
15625ll,
78125ll,
390625ll,
1953125ll,
9765625ll,
48828125ll,
244140625ll,
1220703125ll,
6103515625ll,
30517578125ll,
152587890625ll,
762939453125ll,
3814697265625ll,
19073486328125ll,
95367431640625ll,
476837158203125ll,
2384185791015625ll,
11920928955078125ll,
59604644775390625ll,
298023223876953125ll,
1490116119384765625ll,
7450580596923828125ll
};
#ifndef DISABLE_DTOA
static short int Lhint[2098] = {
/*18,*/19, 19, 19, 19, 20, 20, 20, 21, 21,
21, 22, 22, 22, 23, 23, 23, 23, 24, 24,
24, 25, 25, 25, 26, 26, 26, 26, 27, 27,
@@ -1262,38 +1315,11 @@ typedef struct BF96 { /* Normalized 96-bit software floating point numbers */
641, 642, 642, 642, 643, 643, 643, 644, 644, 644,
644, 645, 645, 645, 646, 646, 646, 647, 647, 647,
647, 648, 648, 648, 649, 649, 649, 650, 650 };
static ULLong pfive[27] = {
5ll,
25ll,
125ll,
625ll,
3125ll,
15625ll,
78125ll,
390625ll,
1953125ll,
9765625ll,
48828125ll,
244140625ll,
1220703125ll,
6103515625ll,
30517578125ll,
152587890625ll,
762939453125ll,
3814697265625ll,
19073486328125ll,
95367431640625ll,
476837158203125ll,
2384185791015625ll,
11920928955078125ll,
59604644775390625ll,
298023223876953125ll,
1490116119384765625ll,
7450580596923828125ll
};
static int pfivebits[25] = {3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31,
33, 35, 38, 40, 42, 45, 47, 49, 52, 54, 56, 59};
#endif
#endif /*}*/
#endif /*}} NO_LONG_LONG */
@@ -1502,9 +1528,9 @@ static unsigned int maxthreads = 0;
#define Kmax 7
#ifdef __cplusplus
extern "C" double strtod(const char *s00, char **se);
extern "C" char *dtoa(double d, int mode, int ndigits,
int *decpt, int *sign, char **rve);
//extern "C" double strtod(const char *s00, char **se);
//extern "C" char *dtoa(double d, int mode, int ndigits,
// int *decpt, int *sign, char **rve);
#endif
struct
@@ -1597,7 +1623,7 @@ Balloc(int k MTd)
#else
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
/sizeof(double);
if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem
if (k <= Kmax && (unsigned long)(pmem_next - private_mem) + len <= PRIVATE_mem
#ifdef MULTIPLE_THREADS
&& TI == TI1
#endif
@@ -2822,6 +2848,7 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
case '-':
esign = 1;
/* no break */
Standard_FALLTHROUGH
case '+':
s++;
}
@@ -3229,7 +3256,7 @@ sulp(U *x, BCinfo *bc)
bigcomp(U *rv, const char *s0, BCinfo *bc MTd)
{
Bigint *b, *d;
int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
int b2, bbits, d2, dd=0, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
dsign = bc->dsign;
nd = bc->nd;
@@ -3429,7 +3456,7 @@ retlow1:
#endif /* NO_STRTOD_BIGCOMP */
double
strtod(const char *s00, char **se)
Strtod(const char *s00, char **se)
{
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1;
int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign;
@@ -3439,7 +3466,7 @@ strtod(const char *s00, char **se)
U aadj2, adj, rv, rv0;
ULong y, z;
BCinfo bc;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
Bigint *bb=0, *bb1=0, *bd=0, *bd0=0, *bs=0, *delta=0;
#ifdef USE_BF96
ULLong bhi, blo, brv, t00, t01, t02, t10, t11, terv, tg, tlo, yz;
const BF96 *p10;
@@ -3479,10 +3506,12 @@ strtod(const char *s00, char **se)
case '-':
sign = 1;
/* no break */
Standard_FALLTHROUGH
case '+':
if (*++s)
goto break2;
/* no break */
Standard_FALLTHROUGH
case 0:
goto ret0;
case '\t':
@@ -3609,6 +3638,7 @@ strtod(const char *s00, char **se)
switch(c = *++s) {
case '-':
esign = 1;
Standard_FALLTHROUGH
case '+':
c = *++s;
}
@@ -4850,6 +4880,9 @@ strtod(const char *s00, char **se)
return sign ? -dval(&rv) : dval(&rv);
}
// disable dtoa() and related functions
#ifndef DISABLE_DTOA
#ifndef MULTIPLE_THREADS
static char *dtoa_result;
#endif
@@ -6196,8 +6229,10 @@ dtoa(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
freedtoa(dtoa_result);
#endif
return dtoa_r(dd, mode, ndigits, decpt, sign, rve, 0, 0);
}
}
#endif /* DISABLE_DTOA */
#ifdef __cplusplus
}
//}
#endif

View File

@@ -1,21 +0,0 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard_GUID.hxx>
#include <Standard_UUID.hxx>
//void Standard_GUID::Assign(const Standard_UUID& uid)
void Standard_GUID::Assign(const Standard_UUID& )
{
}