From: abv Date: Sun, 24 Dec 2017 06:44:04 +0000 (+0300) Subject: 0029399: Optimize reading of floating point values from text strings X-Git-Tag: V7_3_0_beta~105 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=07bbde451a11595140977b457e50b60c35cab354 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. --- diff --git a/dox/overview/overview.md b/dox/overview/overview.md index 5a79b3cfd6..1945bc61a3 100644 --- a/dox/overview/overview.md +++ b/dox/overview/overview.md @@ -136,6 +136,9 @@ FreeImage is easy to use, fast, multithreading safe, compatible with all 32-bit and cross-platform (works both with Linux and Mac OS X). FreeImage is optionally used by OCCT to work with images, on conditions of the FreeImage Public License (FIPL) (http://freeimage.sourceforge.net/freeimage-license.txt). +**David M. Gay's floating point routines** (dtoa.c) are used for fast reading of floating point values from text strings. +These routines are available under MIT-like license (see http://www.netlib.org/fp/). + **CMake** is an open-source, cross-platform family of tools designed to build, test and package software. CMake is used to control the software compilation process using simple platform and compiler independent configuration files, and generate native makefiles and workspaces that can be used in the compiler environment of your choice. OCCT uses CMake as a build system. CMake is available under BSD 3-Clause license. See more at https://cmake.org/ diff --git a/src/BRepMesh/BRepMesh_Vertex.hxx b/src/BRepMesh/BRepMesh_Vertex.hxx index 7cb7d72346..c66bcf669a 100644 --- a/src/BRepMesh/BRepMesh_Vertex.hxx +++ b/src/BRepMesh/BRepMesh_Vertex.hxx @@ -15,11 +15,9 @@ #ifndef _BRepMesh_Vertex_HeaderFile #define _BRepMesh_Vertex_HeaderFile -#include -#include -#include -#include #include +#include +#include //! Light weighted structure representing vertex //! of the mesh in parametric space. Vertex could be diff --git a/src/Interface/Interface_FileReaderData.cxx b/src/Interface/Interface_FileReaderData.cxx index 57b9f3ec70..4349a63a8d 100644 --- a/src/Interface/Interface_FileReaderData.cxx +++ b/src/Interface/Interface_FileReaderData.cxx @@ -241,210 +241,7 @@ void Interface_FileReaderData::Destroy () { } - -#define MAXCHIF 80 - -static const Standard_Real vtab[] = -{ 1., 2., 3., 4., 5., 6., 7., 8., 9., - 10., 20., 30., 40., 50., 60., 70., 80., 90., - 100., 200., 300., 400., 500., 600., 700., 800., 900., - 1000., 2000., 3000., 4000., 5000., 6000., 7000., 8000., 9000., - 10000., 20000., 30000., 40000., 50000., 60000., 70000., 80000., 90000., - 1.E+05, 2.E+05, 3.E+05, 4.E+05, 5.E+05, 6.E+05, 7.E+05, 8.E+05, 9.E+05, - 1.E+06, 2.E+06, 3.E+06, 4.E+06, 5.E+06, 6.E+06, 7.E+06, 8.E+06, 9.E+06, - 1.E+07, 2.E+07, 3.E+07, 4.E+07, 5.E+07, 6.E+07, 7.E+07, 8.E+07, 9.E+07, - 1.E+08, 2.E+08, 3.E+08, 4.E+08, 5.E+08, 6.E+08, 7.E+08, 8.E+08, 9.E+08, - 1.E+09, 2.E+09, 3.E+09, 4.E+09, 5.E+09, 6.E+09, 7.E+09, 8.E+09, 9.E+09, - 1.E+10, 2.E+10, 3.E+10, 4.E+10, 5.E+10, 6.E+10, 7.E+10, 8.E+10, 9.E+10, - 1.E+11, 2.E+11, 3.E+11, 4.E+11, 5.E+11, 6.E+11, 7.E+11, 8.E+11, 9.E+11, - 1.E+12, 2.E+12, 3.E+12, 4.E+12, 5.E+12, 6.E+12, 7.E+12, 8.E+12, 9.E+12, - 1.E+13, 2.E+13, 3.E+13, 4.E+13, 5.E+13, 6.E+13, 7.E+13, 8.E+13, 9.E+13, - 1.E+14, 2.E+14, 3.E+14, 4.E+14, 5.E+14, 6.E+14, 7.E+14, 8.E+14, 9.E+14, - 1.E+15, 2.E+15, 3.E+15, 4.E+15, 5.E+15, 6.E+15, 7.E+15, 8.E+15, 9.E+15, - 1.E+16, 2.E+16, 3.E+16, 4.E+16, 5.E+16, 6.E+16, 7.E+16, 8.E+16, 9.E+16, - 1.E+17, 2.E+17, 3.E+17, 4.E+17, 5.E+17, 6.E+17, 7.E+17, 8.E+17, 9.E+17, - 1.E+18, 2.E+18, 3.E+18, 4.E+18, 5.E+18, 6.E+18, 7.E+18, 8.E+18, 9.E+18, - 1.E+19, 2.E+19, 3.E+19, 4.E+19, 5.E+19, 6.E+19, 7.E+19, 8.E+19, 9.E+19, - 1.E+20, 2.E+20, 3.E+20, 4.E+20, 5.E+20, 6.E+20, 7.E+20, 8.E+20, 9.E+20, - 1.E+21, 2.E+21, 3.E+21, 4.E+21, 5.E+21, 6.E+21, 7.E+21, 8.E+21, 9.E+21, - 1.E+22, 2.E+22, 3.E+22, 4.E+22, 5.E+22, 6.E+22, 7.E+22, 8.E+22, 9.E+22, - 1.E+23, 2.E+23, 3.E+23, 4.E+23, 5.E+23, 6.E+23, 7.E+23, 8.E+23, 9.E+23, - 1.E+24, 2.E+24, 3.E+24, 4.E+24, 5.E+24, 6.E+24, 7.E+24, 8.E+24, 9.E+24, - 1.E+25, 2.E+25, 3.E+25, 4.E+25, 5.E+25, 6.E+25, 7.E+25, 8.E+25, 9.E+25, - 1.E+26, 2.E+26, 3.E+26, 4.E+26, 5.E+26, 6.E+26, 7.E+26, 8.E+26, 9.E+26, - 1.E+27, 2.E+27, 3.E+27, 4.E+27, 5.E+27, 6.E+27, 7.E+27, 8.E+27, 9.E+27, - 1.E+28, 2.E+28, 3.E+28, 4.E+28, 5.E+28, 6.E+28, 7.E+28, 8.E+28, 9.E+28, - 1.E+29, 2.E+29, 3.E+29, 4.E+29, 5.E+29, 6.E+29, 7.E+29, 8.E+29, 9.E+29, - 1.E+30, 2.E+30, 3.E+30, 4.E+30, 5.E+30, 6.E+30, 7.E+30, 8.E+30, 9.E+30, - 1.E+31, 2.E+31, 3.E+31, 4.E+31, 5.E+31, 6.E+31, 7.E+31, 8.E+31, 9.E+31, - 1.E+32, 2.E+32, 3.E+32, 4.E+32, 5.E+32, 6.E+32, 7.E+32, 8.E+32, 9.E+32, - 1.E+33, 2.E+33, 3.E+33, 4.E+33, 5.E+33, 6.E+33, 7.E+33, 8.E+33, 9.E+33, - 1.E+34, 2.E+34, 3.E+34, 4.E+34, 5.E+34, 6.E+34, 7.E+34, 8.E+34, 9.E+34, - 1.E+35, 2.E+35, 3.E+35, 4.E+35, 5.E+35, 6.E+35, 7.E+35, 8.E+35, 9.E+35, - 1.E+36, 2.E+36, 3.E+36, 4.E+36, 5.E+36, 6.E+36, 7.E+36, 8.E+36, 9.E+36, - 1.E+37, 2.E+37, 3.E+37, 4.E+37, 5.E+37, 6.E+37, 7.E+37, 8.E+37, 9.E+37, - 1.E+38, 2.E+38, 3.E+38, 4.E+38, 5.E+38, 6.E+38, 7.E+38, 8.E+38, 9.E+38, - 1.E+39, 2.E+39, 3.E+39, 4.E+39, 5.E+39, 6.E+39, 7.E+39, 8.E+39, 9.E+39, - 1.E+40, 2.E+40, 3.E+40, 4.E+40, 5.E+40, 6.E+40, 7.E+40, 8.E+40, 9.E+40, - 1.E+41, 2.E+41, 3.E+41, 4.E+41, 5.E+41, 6.E+41, 7.E+41, 8.E+41, 9.E+41, - 1.E+42, 2.E+42, 3.E+42, 4.E+42, 5.E+42, 6.E+42, 7.E+42, 8.E+42, 9.E+42, - 1.E+43, 2.E+43, 3.E+43, 4.E+43, 5.E+43, 6.E+43, 7.E+43, 8.E+43, 9.E+43, - 1.E+44, 2.E+44, 3.E+44, 4.E+44, 5.E+44, 6.E+44, 7.E+44, 8.E+44, 9.E+44, - 1.E+45, 2.E+45, 3.E+45, 4.E+45, 5.E+45, 6.E+45, 7.E+45, 8.E+45, 9.E+45, - 1.E+46, 2.E+46, 3.E+46, 4.E+46, 5.E+46, 6.E+46, 7.E+46, 8.E+46, 9.E+46, - 1.E+47, 2.E+47, 3.E+47, 4.E+47, 5.E+47, 6.E+47, 7.E+47, 8.E+47, 9.E+47, - 1.E+48, 2.E+48, 3.E+48, 4.E+48, 5.E+48, 6.E+48, 7.E+48, 8.E+48, 9.E+48, - 1.E+49, 2.E+49, 3.E+49, 4.E+49, 5.E+49, 6.E+49, 7.E+49, 8.E+49, 9.E+49, - 1.E+50, 2.E+50, 3.E+50, 4.E+50, 5.E+50, 6.E+50, 7.E+50, 8.E+50, 9.E+50, - 1.E+51, 2.E+51, 3.E+51, 4.E+51, 5.E+51, 6.E+51, 7.E+51, 8.E+51, 9.E+51, - 1.E+52, 2.E+52, 3.E+52, 4.E+52, 5.E+52, 6.E+52, 7.E+52, 8.E+52, 9.E+52, - 1.E+53, 2.E+53, 3.E+53, 4.E+53, 5.E+53, 6.E+53, 7.E+53, 8.E+53, 9.E+53, - 1.E+54, 2.E+54, 3.E+54, 4.E+54, 5.E+54, 6.E+54, 7.E+54, 8.E+54, 9.E+54, - 1.E+55, 2.E+55, 3.E+55, 4.E+55, 5.E+55, 6.E+55, 7.E+55, 8.E+55, 9.E+55, - 1.E+56, 2.E+56, 3.E+56, 4.E+56, 5.E+56, 6.E+56, 7.E+56, 8.E+56, 9.E+56, - 1.E+57, 2.E+57, 3.E+57, 4.E+57, 5.E+57, 6.E+57, 7.E+57, 8.E+57, 9.E+57, - 1.E+58, 2.E+58, 3.E+58, 4.E+58, 5.E+58, 6.E+58, 7.E+58, 8.E+58, 9.E+58, - 1.E+59, 2.E+59, 3.E+59, 4.E+59, 5.E+59, 6.E+59, 7.E+59, 8.E+59, 9.E+59, - 1.E+60, 2.E+60, 3.E+60, 4.E+60, 5.E+60, 6.E+60, 7.E+60, 8.E+60, 9.E+60, - 1.E+61, 2.E+61, 3.E+61, 4.E+61, 5.E+61, 6.E+61, 7.E+61, 8.E+61, 9.E+61, - 1.E+62, 2.E+62, 3.E+62, 4.E+62, 5.E+62, 6.E+62, 7.E+62, 8.E+62, 9.E+62, - 1.E+63, 2.E+63, 3.E+63, 4.E+63, 5.E+63, 6.E+63, 7.E+63, 8.E+63, 9.E+63, - 1.E+64, 2.E+64, 3.E+64, 4.E+64, 5.E+64, 6.E+64, 7.E+64, 8.E+64, 9.E+64, - 1.E+65, 2.E+65, 3.E+65, 4.E+65, 5.E+65, 6.E+65, 7.E+65, 8.E+65, 9.E+65, - 1.E+66, 2.E+66, 3.E+66, 4.E+66, 5.E+66, 6.E+66, 7.E+66, 8.E+66, 9.E+66, - 1.E+67, 2.E+67, 3.E+67, 4.E+67, 5.E+67, 6.E+67, 7.E+67, 8.E+67, 9.E+67, - 1.E+68, 2.E+68, 3.E+68, 4.E+68, 5.E+68, 6.E+68, 7.E+68, 8.E+68, 9.E+68, - 1.E+69, 2.E+69, 3.E+69, 4.E+69, 5.E+69, 6.E+69, 7.E+69, 8.E+69, 9.E+69, - 1.E+70, 2.E+70, 3.E+70, 4.E+70, 5.E+70, 6.E+70, 7.E+70, 8.E+70, 9.E+70, - 1.E+71, 2.E+71, 3.E+71, 4.E+71, 5.E+71, 6.E+71, 7.E+71, 8.E+71, 9.E+71, - 1.E+72, 2.E+72, 3.E+72, 4.E+72, 5.E+72, 6.E+72, 7.E+72, 8.E+72, 9.E+72, - 1.E+73, 2.E+73, 3.E+73, 4.E+73, 5.E+73, 6.E+73, 7.E+73, 8.E+73, 9.E+73, - 1.E+74, 2.E+74, 3.E+74, 4.E+74, 5.E+74, 6.E+74, 7.E+74, 8.E+74, 9.E+74, - 1.E+75, 2.E+75, 3.E+75, 4.E+75, 5.E+75, 6.E+75, 7.E+75, 8.E+75, 9.E+75, - 1.E+76, 2.E+76, 3.E+76, 4.E+76, 5.E+76, 6.E+76, 7.E+76, 8.E+76, 9.E+76, - 1.E+77, 2.E+77, 3.E+77, 4.E+77, 5.E+77, 6.E+77, 7.E+77, 8.E+77, 9.E+77, - 1.E+78, 2.E+78, 3.E+78, 4.E+78, 5.E+78, 6.E+78, 7.E+78, 8.E+78, 9.E+78, - 1.E+79, 2.E+79, 3.E+79, 4.E+79, 5.E+79, 6.E+79, 7.E+79, 8.E+79, 9.E+79, - 1.E+80, 2.E+80, 3.E+80, 4.E+80, 5.E+80, 6.E+80, 7.E+80, 8.E+80, 9.E+80, - 1.E+81, 2.E+81, 3.E+81, 4.E+81, 5.E+81, 6.E+81, 7.E+81, 8.E+81, 9.E+81, - 1.E+82, 2.E+82, 3.E+82, 4.E+82, 5.E+82, 6.E+82, 7.E+82, 8.E+82, 9.E+82, - 1.E+83, 2.E+83, 3.E+83, 4.E+83, 5.E+83, 6.E+83, 7.E+83, 8.E+83, 9.E+83, - 1.E+84, 2.E+84, 3.E+84, 4.E+84, 5.E+84, 6.E+84, 7.E+84, 8.E+84, 9.E+84, - 1.E+85, 2.E+85, 3.E+85, 4.E+85, 5.E+85, 6.E+85, 7.E+85, 8.E+85, 9.E+85, - 1.E+86, 2.E+86, 3.E+86, 4.E+86, 5.E+86, 6.E+86, 7.E+86, 8.E+86, 9.E+86, - 1.E+87, 2.E+87, 3.E+87, 4.E+87, 5.E+87, 6.E+87, 7.E+87, 8.E+87, 9.E+87, - 1.E+88, 2.E+88, 3.E+88, 4.E+88, 5.E+88, 6.E+88, 7.E+88, 8.E+88, 9.E+88, - 1.E+89, 2.E+89, 3.E+89, 4.E+89, 5.E+89, 6.E+89, 7.E+89, 8.E+89, 9.E+89, - 1.E+90, 2.E+90, 3.E+90, 4.E+90, 5.E+90, 6.E+90, 7.E+90, 8.E+90, 9.E+90, - 1.E+91, 2.E+91, 3.E+91, 4.E+91, 5.E+91, 6.E+91, 7.E+91, 8.E+91, 9.E+91, - 1.E+92, 2.E+92, 3.E+92, 4.E+92, 5.E+92, 6.E+92, 7.E+92, 8.E+92, 9.E+92, - 1.E+93, 2.E+93, 3.E+93, 4.E+93, 5.E+93, 6.E+93, 7.E+93, 8.E+93, 9.E+93, - 1.E+94, 2.E+94, 3.E+94, 4.E+94, 5.E+94, 6.E+94, 7.E+94, 8.E+94, 9.E+94, - 1.E+95, 2.E+95, 3.E+95, 4.E+95, 5.E+95, 6.E+95, 7.E+95, 8.E+95, 9.E+95, - 1.E+96, 2.E+96, 3.E+96, 4.E+96, 5.E+96, 6.E+96, 7.E+96, 8.E+96, 9.E+96, - 1.E+97, 2.E+97, 3.E+97, 4.E+97, 5.E+97, 6.E+97, 7.E+97, 8.E+97, 9.E+97, - 1.E+98, 2.E+98, 3.E+98, 4.E+98, 5.E+98, 6.E+98, 7.E+98, 8.E+98, 9.E+98, - 1.E+99, 2.E+99, 3.E+99, 4.E+99, 5.E+99, 6.E+99, 7.E+99, 8.E+99, 9.E+99 }; - - - Standard_Real Interface_FileReaderData::Fastof (const Standard_CString ligne) +Standard_Real Interface_FileReaderData::Fastof (const Standard_CString ligne) { - Standard_Real val = 0., valdiv; - int i, jj, j, k, je, jx; - int chiffre[MAXCHIF]; int point, prem, moins, exp, grexp; - j = jj = je = jx = 0; - moins = exp = grexp = 0; - prem = MAXCHIF + 1; point = -1; // ligne[MAXCHIF+1] = '\0'; fin forcee - -/* Analyse de la ligne (reputee representer un Flottant) */ - for (i = 0; ; i ++) // critere d arret : cf '\0' - { - const char& car = ligne[i]; -/* critere d arret : ne pas l oublier, mais eviter de freiner le traitement - DONC, une fois en fin, plus une fois pour 1er passage - if (car == '\0') - { if (point < 0) { point = i; jx = point - prem; }; break; } */ - - if (prem > MAXCHIF) - { - if (car == '0') continue; - if (car == '.') { point = i; continue; } - if (car == '+') continue; - if (car == '-') { moins = 1; continue; } - if (car == '\0') - { - if (point < 0) - { - point = i; - jx = point - prem; - } - break; - } - if (car < 33) - { - continue; - } - prem = i; - if (point >= 0) - { - jx = point - prem + 1; - } - } - if (car > 48 && car <= 57) - { - chiffre[j] = car - 48; - jj = ++j; // j++ puis jj = j - continue; - } - if (car == '0') { chiffre[j] = 0; j ++; continue; } - if (car == '.') { point = i; jx = point - prem; continue; } - if ((car & 94) == 68) { // prend : e E d D - je = i; exp = atoi(&ligne[i+1]); jx += exp; - if (exp < -100 || exp > 100) - { - grexp = 1; - } - break; - } - if (car == '\0') - { - if (point < 0) - { - point = i; - jx = point - prem; - } - break; - } - } - -/* Interpretation : on decale le Point Decimal selon l Exposant - Puis on considere par rapport a , : - chiffre[i, pour i < point - prem] : partie entiere - chiffre[i, pour i >= point - prem] : partie decimale -*/ - -// jx = (point < prem ? point - prem + 1 : point - prem) + exp; deja calcule -// Puissance de 10 premiere decimale <0> -// limite : le PLUS PETIT SIGNIFIANT doit etre >= 1e-99 - je = jx*9; - if (jx > jj) { - valdiv = 1.; - if (jx >= 100 || grexp) return Atof(ligne); // issue de secours - } else { - k = jj*9; - if (jj >= 100 || grexp || (k-je >= 900)) return Atof(ligne); // issue de secours - valdiv = vtab[k-je]; - je = k; - } - - je --; -// val = 0.; mis a la creation - for (i = 0; i < jj; i ++) { - je -= 9; - const int& chif = chiffre[i]; - if (chif != 0) val += vtab[chif+je]; - } - if (valdiv != 1.) val = val/valdiv; - if (moins) val = -val; - return val; + return Strtod (ligne, 0); } diff --git a/src/QANCollection/QANCollection_Test.cxx b/src/QANCollection/QANCollection_Test.cxx index 493a1770b4..03e10cb0cc 100644 --- a/src/QANCollection/QANCollection_Test.cxx +++ b/src/QANCollection/QANCollection_Test.cxx @@ -22,6 +22,7 @@ #include #include +#include #include @@ -863,6 +864,251 @@ static Standard_Integer QANColTestArrayMove (Draw_Interpretor& di, Standard_Inte return 0; } +#include +#include + +static inline double test_atof (const char* theStr) +{ + return atof (theStr); +} + +static inline double test_Atof (const char* theStr) +{ + return Atof (theStr); +} + +static inline double test_strtod (const char* theStr) +{ + char *end; + return strtod (theStr, &end); +} + +static inline double test_Strtod (const char* theStr) +{ + char *end; + return Strtod (theStr, &end); +} + +static inline double test_sscanf (const char* theStr) +{ + double val = 0.; + sscanf (theStr, "%lf", &val); + return val; +} + +static int check_atof (const NCollection_Array2& theStrings, const char* theFormat, + double (*test_func)(const char*), Draw_Interpretor& di) +{ + int aNbErr = 0; + for (int i = 0; i < theStrings.UpperRow(); i++) + { + const char *aStr= &theStrings(i,0); + char buff[256]; + double aVal = test_func (aStr); + Sprintf (buff, theFormat, aVal); + if (strcasecmp (buff, &theStrings(i,0))) + { +#if defined(_MSC_VER) && _MSC_VER < 1900 + // MSVC < 2015 prints nan and inf as 1.#NAN or 1.INF, and noes not recognize nan or inf on read + if (strstr (aStr, "1.#") || strstr (aStr, "nan") || strstr (aStr, "inf") || + strstr (aStr, "NAN") || strstr (aStr, "INF")) + continue; +#endif + if (aNbErr < 5) + { + di << "Deviation parsing " << aStr << " and print back: " << buff << "\n"; + } + aNbErr++; + } + } + return aNbErr; +} + +// Test speed of standard and OCCT-specific (accelerated) functions to parse string to double +static Standard_Integer QATestAtof (Draw_Interpretor& di, Standard_Integer argc, const char ** argv) +{ + int aNbToTest = Max (100, (argc > 1 ? Draw::Atoi(argv[1]) : 1000000)); + int aNbDigits = (argc > 2 ? Draw::Atoi(argv[2]) : 10); + double aRangeMin = (argc > 3 ? Draw::Atof(argv[3]) : -1e9); + double aRangeMax = (argc > 4 ? Draw::Atof(argv[4]) : 1e9); + + char aFormat[256]; + Sprintf (aFormat, "%%.%dlg", Max (2, Min (20, aNbDigits))); + + // prepare data + const int MAXLEN = 256; + NCollection_Array2 aValuesStr (0, aNbToTest - 1, 0, MAXLEN); + math_BullardGenerator aRandom; + + if (aRangeMin < aRangeMax) + { + // random values within specified range +// std::default_random_engine aRandomEngine; +// std::uniform_real_distribution aRandomDistr (aRangeMin, aRangeMax); + const uint64_t aMaxUInt64 = ~(uint64_t)0; // could be (not supported by old GCC): std::numeric_limits::max() + for (int i = 0; i < aNbToTest; i++) + { +// double aVal = aRandomDistr (aRandomEngine); + uint64_t aIVal = ((uint64_t)aRandom.NextInt() << 32) + aRandom.NextInt(); + double aVal = aRangeMin + (aIVal / (double)aMaxUInt64) * (aRangeMax - aRangeMin); + Sprintf(&aValuesStr(i,0), aFormat, aVal); + } + } + else + { + // special values + int i = 0; + + strcpy (&aValuesStr(i++,0), "nan"); + strcpy (&aValuesStr(i++,0), "nan(qnan)"); + strcpy (&aValuesStr(i++,0), "NAN"); + strcpy (&aValuesStr(i++,0), "-nan"); + strcpy (&aValuesStr(i++,0), "-NAN"); + strcpy (&aValuesStr(i++,0), "inf"); + strcpy (&aValuesStr(i++,0), "INF"); + strcpy (&aValuesStr(i++,0), "-inf"); + strcpy (&aValuesStr(i++,0), "-INF"); + + strcpy (&aValuesStr(i++,0), " ."); // standalone period should not be considered as a number + strcpy (&aValuesStr(i++,0), "nanabcdef_128 xx"); // extra non-parenthised sequence after "nan" + + strcpy (&aValuesStr(i++,0), "905791934.11394954"); // value that gets rounded in a wrong way by fast Strtod() + strcpy (&aValuesStr(i++,0), "9.343962790444495e+148"); // value where strtod() and Strtod() differ by 2 Epsilon + + strcpy (&aValuesStr(i++,0), " 12345.67text"); // test for leading whitespaces and trailing text + strcpy (&aValuesStr(i++,0), "000.000"); // test for zero + strcpy (&aValuesStr(i++,0), "000.000e-0002"); // test for zero + + strcpy (&aValuesStr(i++,0), "1000000000000000000000000000012345678901234567890"); // huge mantissa + strcpy (&aValuesStr(i++,0), "0000000000.00000000000000000012345678901234567890"); // leading zeros + strcpy (&aValuesStr(i++,0), "1.00000000000000000000000000012345678901234567890"); // long fractional part + + strcpy (&aValuesStr(i++,0), "0.0000000001e318"); // large exponent but no overflow + strcpy (&aValuesStr(i++,0), "-1.7976931348623158e+308"); // -DBL_MAX + strcpy (&aValuesStr(i++,0), "1.79769313486232e+308"); // overflow + + strcpy (&aValuesStr(i++,0), "10000000000e-310"); // large negative exponent but no underflow + strcpy (&aValuesStr(i++,0), "1.1e-310"); // underflow + strcpy (&aValuesStr(i++,0), "0.000001e-310"); // underflow + strcpy (&aValuesStr(i++,0), "2.2250738585072014e-308"); // underflow, DBL_MIN + strcpy (&aValuesStr(i++,0), "2.2250738585e-308"); // underflow, value less than DBL_MIN + + strcpy (&aValuesStr(i++,0), "2.2204460492503131e-016"); // DBL_EPSILON + + // random binary data +// std::default_random_engine aRandomEngine; +// std::uniform_int_distribution aRandomDistr (0, ~(uint64_t)0); + for (; i < aNbToTest; i++) + { + union { + uint64_t valint; + double valdbl; + } aVal; +// aVal.valint = aRandomDistr (aRandomEngine); + aVal.valint = ((uint64_t)aRandom.NextInt() << 32) + aRandom.NextInt(); + Sprintf(&aValuesStr(i,0), aFormat, aVal.valdbl); + } + } + + // test different methods +#define TEST_ATOF(method) \ + OSD_Timer aT_##method; aT_##method.Start(); \ + double aRes_##method = 0.; \ + for (int i = 0; i < aNbToTest; i++) { aRes_##method += test_##method (&aValuesStr(i,0)); } \ + aT_##method.Stop() + + TEST_ATOF(sscanf); + TEST_ATOF(strtod); + TEST_ATOF(atof); + TEST_ATOF(Strtod); + TEST_ATOF(Atof); +#undef TEST_ATOF + + // test different methods +#define CHECK_ATOF(method) \ + int aNbErr_##method = check_atof (aValuesStr, aFormat, test_##method, di); \ + di << "Checking " << #method << ": " << aNbErr_##method << " deviations\n" + + CHECK_ATOF(sscanf); + CHECK_ATOF(strtod); + CHECK_ATOF(atof); + CHECK_ATOF(Strtod); + CHECK_ATOF(Atof); +#undef CHECK_ATOF + +/* compare results with atof */ +#ifdef _MSC_VER +#define ISFINITE _finite +#else +#define ISFINITE std::isfinite +#endif + int nbErr = 0; + for (int i = 0; i < aNbToTest; i++) + { + char *aStr = &aValuesStr(i,0), *anEndOCCT, *anEndStd; + double aRes = Strtod (aStr, &anEndOCCT); + double aRef = strtod (aStr, &anEndStd); + if (ISFINITE(aRes) != ISFINITE(aRef)) + { + nbErr++; +#if defined(_MSC_VER) && _MSC_VER < 1900 + // MSVC < 2015 prints nan and inf as 1.#NAN or 1.INF, and noes not recognize nan or inf on read + if (strstr (aStr, "1.#") || strstr (aStr, "nan") || strstr (aStr, "inf") || + strstr (aStr, "NAN") || strstr (aStr, "INF")) + continue; +#endif + if (nbErr < 5) + { + char aBuff[256]; + Sprintf (aBuff, "Error parsing %s: %.20lg / %.20lg\n", aStr, aRes, aRef); + di << aBuff; + } + } + else if (ISFINITE(aRef) && Abs (aRes - aRef) > Epsilon (aRef)) + { + nbErr++; + if (nbErr < 5) + { + char aBuff[256]; + Sprintf (aBuff, "Error parsing %s: %.20lg / %.20lg\n", aStr, aRes, aRef); + di << aBuff; + Sprintf (aBuff, "[Delta = %.8lg, Epsilon = %.8lg]\n", Abs (aRes - aRef), Epsilon (aRef)); + di << aBuff; + } + } + + // check that Strtod() and strtod() stop at the same place; + // this makes sense for reading special values such as "nan" and thus + // is not relevant for MSVC 2010 and earlier than do not support these +#if ! defined(_MSC_VER) || _MSC_VER >= 1700 + if (anEndOCCT != anEndStd) + { + nbErr++; + if (nbErr < 5) + di << "Error: different number of symbols parsed in " + << aStr << ": " << (int)(anEndOCCT - aStr) << " / " << (int)(anEndStd - aStr) << "\n"; + } +#endif + } + di << "Total " << nbErr << " defiations from strtod() found\n"; +/* */ + + // print results + di << "Method\t CPU\t Elapsed \t Deviations \tChecksum\n"; + +#define PRINT_RES(method) \ + di << #method "\t" << aT_##method.UserTimeCPU() << " \t" << aT_##method.ElapsedTime() << "\t" \ + << aNbErr_##method << "\t" << aRes_##method << "\n" + PRINT_RES(sscanf); + PRINT_RES(strtod); + PRINT_RES(atof); + PRINT_RES(Strtod); + PRINT_RES(Atof); +#undef PRINT_RES + + return 0; +} + void QANCollection::CommandsTest(Draw_Interpretor& theCommands) { const char *group = "QANCollection"; @@ -877,5 +1123,6 @@ void QANCollection::CommandsTest(Draw_Interpretor& theCommands) { theCommands.Add("QANColTestList", "QANColTestList", __FILE__, QANColTestList, group); theCommands.Add("QANColTestSequence", "QANColTestSequence", __FILE__, QANColTestSequence, group); theCommands.Add("QANColTestVector", "QANColTestVector", __FILE__, QANColTestVector, group); - theCommands.Add("QANColTestArrayMove", "QANColTestArrayMove (is expected to give error)", __FILE__, QANColTestArrayMove, group); + theCommands.Add("QANColTestArrayMove", "QANColTestArrayMove (is expected to give error)", __FILE__, QANColTestArrayMove, group); + theCommands.Add("QATestAtof", "QATestAtof [nbvalues [nbdigits [min [max]]]]", __FILE__, QATestAtof, group); } diff --git a/src/RWStl/RWStl_Reader.cxx b/src/RWStl/RWStl_Reader.cxx index 29f669f378..cb49a570f0 100644 --- a/src/RWStl/RWStl_Reader.cxx +++ b/src/RWStl/RWStl_Reader.cxx @@ -235,6 +235,23 @@ static inline bool str_starts_with (const char* theStr, const char* theWord, int return !strncmp (theStr, theWord, theN); } +static bool ReadVertex (const char* theStr, double& theX, double& theY, double& theZ) +{ + const char *aStr = theStr; + + // skip 'vertex' + while (isspace ((unsigned char)*aStr) || isalpha ((unsigned char)*aStr)) + ++aStr; + + // read values + char *aEnd; + theX = Strtod (aStr, &aEnd); + theY = Strtod (aStr = aEnd, &aEnd); + theZ = Strtod (aStr = aEnd, &aEnd); + + return aEnd != aStr; +} + //============================================================================== //function : ReadAscii //purpose : @@ -314,11 +331,9 @@ Standard_Boolean RWStl_Reader::ReadAscii (Standard_IStream& theStream, aNbLine += 5; Standard_Real x1, y1, z1, x2, y2, z2, x3, y3, z3; - Standard_Integer aReadCount = // read 3 lines "vertex x y z" - sscanf_l (aLine1, aLocale, "%*s %lf %lf %lf", &x1, &y1, &z1) + - sscanf_l (aLine2, aLocale, "%*s %lf %lf %lf", &x2, &y2, &z2) + - sscanf_l (aLine3, aLocale, "%*s %lf %lf %lf", &x3, &y3, &z3); - if (aReadCount != 9) + if (! ReadVertex (aLine1, x1, y1, z1) || + ! ReadVertex (aLine2, x2, y2, z2) || + ! ReadVertex (aLine3, x3, y3, z3)) { TCollection_AsciiString aStr ("Error: cannot read vertex co-ordinates at line "); aStr += aNbLine; diff --git a/src/Standard/FILES b/src/Standard/FILES index da33f5a0e9..a8c48a1745 100755 --- a/src/Standard/FILES +++ b/src/Standard/FILES @@ -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 diff --git a/src/Standard/Standard_CString.cxx b/src/Standard/Standard_CString.cxx index d10974fafb..9e05938100 100755 --- a/src/Standard/Standard_CString.cxx +++ b/src/Standard/Standard_CString.cxx @@ -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) { diff --git a/src/Standard/Standard_CString.hxx b/src/Standard/Standard_CString.hxx index f28414f0bd..798e346296 100644 --- a/src/Standard/Standard_CString.hxx +++ b/src/Standard/Standard_CString.hxx @@ -17,73 +17,65 @@ #ifndef _Standard_CString_HeaderFile # define _Standard_CString_HeaderFile -# ifndef _Standard_TypeDef_HeaderFile -# include -# endif +#include + +# include +# include # if defined(_MSC_VER) && ! defined(strcasecmp) # define strcasecmp _stricmp # endif -# include -# include +// C++ only definitions +#ifdef __cplusplus -# ifndef _Standard_Integer_HeaderFile -# include -# endif +#include + +//! 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); -__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); - -//! 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, ...); - -//============================================================================ -//==== IsEqual : Returns Standard_True if two booleans have the same value -//============================================================================ -inline Standard_Boolean IsEqual(const Standard_CString One - ,const Standard_CString Two) +//! 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); + +//! 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 (strcmp(One,Two) == 0); +// return (Abs( HashCodes( Value , Len ) ) % Upper ) + 1 ; + return HashCode (HashCodes (theStr, theLen), theUpper); } -//============================================================================ -//==== 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 ) +//! Returns Standard_True if two strings are equal +inline Standard_Boolean IsEqual (const Standard_CString theOne, const Standard_CString theTwo) { - aHashCode = HashCodes( Value , Len ); -// return (Abs( aHashCode ) % Upper ) + 1 ; - return HashCode( (Standard_Integer)aHashCode , Upper ) ; + return strcmp (theOne, theTwo) == 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 ) -{ -// return (Abs( HashCodes( Value , Len ) ) % Upper ) + 1 ; - return HashCode( (Standard_Integer) HashCodes( Value , Len ) , Upper ) ; +#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 diff --git a/src/Standard/Standard_GUID.cxx b/src/Standard/Standard_GUID.cxx index 459a60d964..7896d4196f 100644 --- a/src/Standard/Standard_GUID.cxx +++ b/src/Standard/Standard_GUID.cxx @@ -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) +{ + Assign (theUUID); +} + +void Standard_GUID::Assign (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] ; + 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]; } //======================================================================= diff --git a/src/Standard/Standard_SStream.cxx b/src/Standard/Standard_SStream.cxx deleted file mode 100644 index df42f6159d..0000000000 --- a/src/Standard/Standard_SStream.cxx +++ /dev/null @@ -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. diff --git a/src/Standard/Standard_Strtod.cxx b/src/Standard/Standard_Strtod.cxx index a2f9df7a95..002ee6826f 100644 --- a/src/Standard/Standard_Strtod.cxx +++ b/src/Standard/Standard_Strtod.cxx @@ -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 + +#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 diff --git a/src/Standard/Standard_UUID.cxx b/src/Standard/Standard_UUID.cxx deleted file mode 100644 index 8e6a12cd14..0000000000 --- a/src/Standard/Standard_UUID.cxx +++ /dev/null @@ -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 -#include - -//void Standard_GUID::Assign(const Standard_UUID& uid) -void Standard_GUID::Assign(const Standard_UUID& ) -{ -} diff --git a/tests/de/step_1/A3 b/tests/de/step_1/A3 index c94a8788e0..0241b6353f 100644 --- a/tests/de/step_1/A3 +++ b/tests/de/step_1/A3 @@ -8,7 +8,7 @@ set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 42 ( 58 ) Summary = 42 ( 58 ) CHECKSHAPE : Wires = 0 ( 0 ) Faces = 0 ( 0 ) Shells = 0 ( 0 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 0 ( 0 ) Shell = 49 ( 0 ) Face = 49 ( 49 ) Summary = 579 ( 529 ) +NBSHAPES : Solid = 0 ( 0 ) Shell = 49 ( 0 ) Face = 49 ( 49 ) Summary = 579 ( 530 ) STATSHAPE : Solid = 0 ( 0 ) Shell = 49 ( 0 ) Face = 49 ( 49 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 220 ( 218 ) TOLERANCE : MaxTol = 0.003591433268 ( 0.006121716429 ) AvgTol = 0.0002657130942 ( 0.0004625449099 ) LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) diff --git a/tests/de/step_3/E6 b/tests/de/step_3/E6 index 2611c72da1..cc25fb9749 100755 --- a/tests/de/step_3/E6 +++ b/tests/de/step_3/E6 @@ -7,9 +7,9 @@ set filename Z8M6SAT.stp set ref_data { DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 ) TPSTAT : Faulties = 0 ( 0 ) Warnings = 940 ( 3170 ) Summary = 940 ( 3170 ) -CHECKSHAPE : Wires = 49 ( 43 ) Faces = 50 ( 49 ) Shells = 0 ( 2 ) Solids = 0 ( 0 ) -NBSHAPES : Solid = 28 ( 28 ) Shell = 768 ( 30 ) Face = 3240 ( 3239 ) Summary = 29365 ( 28618 ) -STATSHAPE : Solid = 28 ( 28 ) Shell = 768 ( 30 ) Face = 3240 ( 3239 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 12581 ( 12573 ) +CHECKSHAPE : Wires = 45 ( 44 ) Faces = 46 ( 42 ) Shells = 0 ( 2 ) Solids = 0 ( 0 ) +NBSHAPES : Solid = 28 ( 28 ) Shell = 768 ( 30 ) Face = 3240 ( 3239 ) Summary = 29368 ( 28620 ) +STATSHAPE : Solid = 28 ( 28 ) Shell = 768 ( 30 ) Face = 3240 ( 3239 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 12582 ( 12573 ) TOLERANCE : MaxTol = 15.00300076 ( 20.46526799 ) AvgTol = 0.02248945623 ( 0.03724082116 ) LABELS : N0Labels = 3 ( 3 ) N1Labels = 2 ( 2 ) N2Labels = 0 ( 0 ) TotalLabels = 5 ( 5 ) NameLabels = 5 ( 5 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 ) PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 ) diff --git a/tests/perf/draw/restore b/tests/perf/draw/restore new file mode 100644 index 0000000000..9cd505c3df --- /dev/null +++ b/tests/perf/draw/restore @@ -0,0 +1,11 @@ +puts "# ======================================================================" +puts "# 0029399: Optimize reading of floating point values from text strings " +puts "# ======================================================================" +puts "" +puts "# Test to monitor performance of reading large BREP file" + +set file [locate_data_file OCC54.brep] + +dchrono s restart +restore $file a +dchrono s stop counter "restore" diff --git a/tests/perf/fclasses/strtod b/tests/perf/fclasses/strtod new file mode 100644 index 0000000000..aa4c254e44 --- /dev/null +++ b/tests/perf/fclasses/strtod @@ -0,0 +1,48 @@ +puts "=================================================================" +puts "Testing performance of Strtod() vs. standard strtod()" +puts "=================================================================" +puts "" + +pload QAcommands + +# Check that performance of Strtod() and Atof() is at least twice better +# than that of standard strtod() and atof() +proc CheckAtof {nbvalues nbdigits min max} { + set res [QATestAtof $nbvalues $nbdigits $min $max] +# puts $res + + if { ! [regexp {atof\s+([0-9.]+)} $res bidon cpu_atof] || + ! [regexp {Atof\s+([0-9.]+)} $res bidon cpu_Atof] || + ! [regexp {strtod\s+([0-9.]+)} $res bidon cpu_strtod] || + ! [regexp {Strtod\s+([0-9.]+)} $res bidon cpu_Strtod] } { + puts "Error: cannot interpret results of test command!" + } else { + if { $cpu_atof < 2 * $cpu_Atof } { + puts "Error: Atof() is expected to be at least 2 times better than atof()!" + } + if { $cpu_strtod < 2 * $cpu_Strtod } { + puts "Error: Strtod() is expected to be at least 2 times better than strtod()!" + } + } +} + +puts "1M random values, 10 significant digits, in range (-1e9, 1e9)" +CheckAtof 1000000 10 -1e9 1e9 + +puts "1M random values, 10 significant digits, in range (-1e305, 1e305)" +CheckAtof 1000000 10 -1e305 1e305 + +puts "1M random values, 16 significant digits, in range (-1e9, 1e9)" +CheckAtof 1000000 16 -1e9 1e9 + +puts "1M random values, 18 significant digits, in range (-1e305, 1e305)" +CheckAtof 1000000 16 -1e305 1e305 + +# Disarm FPE signals - otherwise they will be raised if signaling NAN appears +dsetsignal 0 + +puts "Special values + 1M values defined by random binary data, 10 digits" +CheckAtof 1000000 10 0 0 + +puts "Special values + 1M values defined by random binary data, 16 digits" +CheckAtof 1000000 16 0 0