mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Add fast_float for float parsing.
2x faster than both std::from_chars and strtod on Windows. macOS will get to benefit from a modern from_chars impl too.
This commit is contained in:
parent
8acf5c1a25
commit
b3de964eff
@ -269,6 +269,7 @@ target_link_libraries( kicommon
|
|||||||
kiplatform
|
kiplatform
|
||||||
nlohmann_json
|
nlohmann_json
|
||||||
nlohmann_json_schema_validator
|
nlohmann_json_schema_validator
|
||||||
|
FastFloat::fast_float
|
||||||
fmt::fmt
|
fmt::fmt
|
||||||
CURL::libcurl
|
CURL::libcurl
|
||||||
picosha2
|
picosha2
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <charconv>
|
#include <fast_float/fast_float.h>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib> // bsearch()
|
#include <cstdlib> // bsearch()
|
||||||
@ -861,43 +861,13 @@ wxArrayString* DSNLEXER::ReadCommentLines()
|
|||||||
|
|
||||||
double DSNLEXER::parseDouble()
|
double DSNLEXER::parseDouble()
|
||||||
{
|
{
|
||||||
// We try here to be locale independent to avoid the need to switch to a "C" locale
|
// Use fast_float::from_chars which is designed to be locale independent and significantly
|
||||||
#if ( defined( __GNUC__ ) && __GNUC__ < 11 ) || ( defined( __clang__ ) && __clang_major__ < 13 )
|
// faster than strtod and std::from_chars
|
||||||
// GCC older than 11 "supports" C++17 without supporting the C++17 std::from_chars for doubles
|
|
||||||
// clang is similar
|
|
||||||
|
|
||||||
// Use wxString::ToCDouble() which is designed to be locale independent
|
|
||||||
wxString tmp = CurStr();
|
|
||||||
double fval;
|
|
||||||
bool success = tmp.ToCDouble( &fval );
|
|
||||||
|
|
||||||
if( !success )
|
|
||||||
{
|
|
||||||
wxString error;
|
|
||||||
error.Printf( _( "Invalid floating point number in\nfile: '%s'\nline: %d\noffset: %d" ),
|
|
||||||
CurSource(), CurLineNumber(), CurOffset() );
|
|
||||||
|
|
||||||
THROW_IO_ERROR( error );
|
|
||||||
}
|
|
||||||
|
|
||||||
return fval;
|
|
||||||
#else
|
|
||||||
// Use std::from_chars which is designed to be locale independent and performance oriented
|
|
||||||
// for data interchange
|
|
||||||
|
|
||||||
const std::string& str = CurStr();
|
const std::string& str = CurStr();
|
||||||
|
|
||||||
// Offset any leading whitespace, this is one thing from_chars does not handle
|
|
||||||
size_t woff = 0;
|
|
||||||
|
|
||||||
while( std::isspace( str[woff] ) && woff < str.length() )
|
|
||||||
{
|
|
||||||
woff++;
|
|
||||||
}
|
|
||||||
|
|
||||||
double dval{};
|
double dval{};
|
||||||
std::from_chars_result res =
|
fast_float::from_chars_result res = fast_float::from_chars( str.data(), str.data() + str.size(), dval,
|
||||||
std::from_chars( str.data() + woff, str.data() + str.size(), dval );
|
fast_float::chars_format::skip_white_space );
|
||||||
|
|
||||||
if( res.ec != std::errc() )
|
if( res.ec != std::errc() )
|
||||||
{
|
{
|
||||||
@ -906,5 +876,4 @@ double DSNLEXER::parseDouble()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return dval;
|
return dval;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <charconv>
|
#include <fast_float/fast_float.h>
|
||||||
#include <sim/sim_value.h>
|
#include <sim/sim_value.h>
|
||||||
#include <wx/translation.h>
|
#include <wx/translation.h>
|
||||||
#include <ki_exception.h>
|
#include <ki_exception.h>
|
||||||
@ -382,22 +382,20 @@ std::string SIM_VALUE::ConvertNotation( const std::string& aString, NOTATION aFr
|
|||||||
int exponent = parseResult.exponent ? *parseResult.exponent : 0;
|
int exponent = parseResult.exponent ? *parseResult.exponent : 0;
|
||||||
exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0;
|
exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0;
|
||||||
|
|
||||||
try
|
int expReduction = 0;
|
||||||
{
|
std::string prefix = SIM_VALUE_PARSER::ExponentToUnitPrefix( exponent, expReduction,
|
||||||
int expReduction = 0;
|
aToNotation );
|
||||||
std::string prefix = SIM_VALUE_PARSER::ExponentToUnitPrefix( exponent, expReduction,
|
double significand{};
|
||||||
aToNotation );
|
|
||||||
double significand{};
|
|
||||||
wxString( parseResult.significand ).ToCDouble( &significand );
|
|
||||||
|
|
||||||
exponent -= expReduction;
|
fast_float::from_chars(
|
||||||
return fmt::format( "{:g}{}", significand * std::pow( 10, exponent ),
|
parseResult.significand.data(),
|
||||||
prefix );
|
parseResult.significand.data() + parseResult.significand.size(),
|
||||||
}
|
significand,
|
||||||
catch( const std::invalid_argument& )
|
fast_float::chars_format::skip_white_space | fast_float::chars_format::allow_leading_plus );
|
||||||
{
|
|
||||||
// best efforts
|
exponent -= expReduction;
|
||||||
}
|
return fmt::format( "{:g}{}", significand * std::pow( 10, exponent ),
|
||||||
|
prefix );
|
||||||
}
|
}
|
||||||
|
|
||||||
return aString;
|
return aString;
|
||||||
@ -446,19 +444,17 @@ double SIM_VALUE::ToDouble( const std::string& aString, double aDefault )
|
|||||||
|
|
||||||
if( parseResult.isOk && !parseResult.isEmpty && !parseResult.significand.empty() )
|
if( parseResult.isOk && !parseResult.isEmpty && !parseResult.significand.empty() )
|
||||||
{
|
{
|
||||||
try
|
int exponent = parseResult.exponent ? *parseResult.exponent : 0;
|
||||||
{
|
|
||||||
LOCALE_IO toggle;
|
|
||||||
int exponent = parseResult.exponent ? *parseResult.exponent : 0;
|
|
||||||
|
|
||||||
exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0;
|
exponent += parseResult.unitPrefixExponent ? *parseResult.unitPrefixExponent : 0;
|
||||||
|
double significand{};
|
||||||
|
|
||||||
return std::stod( parseResult.significand ) * std::pow( 10, exponent );
|
fast_float::from_chars( parseResult.significand.data(),
|
||||||
}
|
parseResult.significand.data() + parseResult.significand.size(),
|
||||||
catch( const std::invalid_argument& )
|
significand,
|
||||||
{
|
fast_float::chars_format::skip_white_space | fast_float::chars_format::allow_leading_plus );
|
||||||
// best efforts
|
|
||||||
}
|
return significand * std::pow( 10, exponent );
|
||||||
}
|
}
|
||||||
|
|
||||||
return aDefault;
|
return aDefault;
|
||||||
|
2
thirdparty/CMakeLists.txt
vendored
2
thirdparty/CMakeLists.txt
vendored
@ -48,6 +48,8 @@ add_subdirectory( delaunator )
|
|||||||
add_subdirectory( dxflib_qcad )
|
add_subdirectory( dxflib_qcad )
|
||||||
add_subdirectory( dynamic_bitset )
|
add_subdirectory( dynamic_bitset )
|
||||||
add_subdirectory( expected )
|
add_subdirectory( expected )
|
||||||
|
set( FASTFLOAT_INSTALL OFF )
|
||||||
|
add_subdirectory( fast_float )
|
||||||
set( FMT_INSTALL OFF )
|
set( FMT_INSTALL OFF )
|
||||||
add_subdirectory( fmt )
|
add_subdirectory( fmt )
|
||||||
add_subdirectory( gzip-hpp )
|
add_subdirectory( gzip-hpp )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user