Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/pjl-misc into lp:zorba.
Commit message: Eliminated slight performance degradation in ato*() functions. It turns out that passing nullptr as a default argument (when nullptr is our own implementation, not the C++11 version) is a tad slow presumably because each instance must be initialized. Changing this to use a global singleton instance eliminates the performance degradation. Requested reviews: Paul J. Lucas (paul-lucas) For more details, see: https://code.launchpad.net/~paul-lucas/zorba/pjl-misc/+merge/143386 Eliminated slight performance degradation in ato*() functions. It turns out that passing nullptr as a default argument (when nullptr is our own implementation, not the C++11 version) is a tad slow presumably because each instance must be initialized. Changing this to use a global singleton instance eliminates the performance degradation. -- https://code.launchpad.net/~paul-lucas/zorba/pjl-misc/+merge/143386 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/util/CMakeLists.txt' --- src/util/CMakeLists.txt 2013-01-04 16:08:03 +0000 +++ src/util/CMakeLists.txt 2013-01-15 19:20:28 +0000 @@ -37,6 +37,10 @@ http_util.h http_util.cpp) +IF (NOT ZORBA_CXX_NULLPTR) + LIST(APPEND UTIL_SRCS cxx_util.cpp) +ENDIF (NOT ZORBA_CXX_NULLPTR) + IF(ZORBA_WITH_FILE_ACCESS) LIST(APPEND UTIL_SRCS mmap_file.cpp) ENDIF(ZORBA_WITH_FILE_ACCESS) === added file 'src/util/cxx_util.cpp' --- src/util/cxx_util.cpp 1970-01-01 00:00:00 +0000 +++ src/util/cxx_util.cpp 2013-01-15 19:20:28 +0000 @@ -0,0 +1,31 @@ +/* + * Copyright 2006-2008 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <zorba/config.h> + +/////////////////////////////////////////////////////////////////////////////// + +#ifndef ZORBA_CXX_NULLPTR + +#include "cxx_util.h" + +zorba::nullptr_type const zorba_nullptr = { }; + +#endif /* ZORBA_CXX_NULLPTR */ + +/////////////////////////////////////////////////////////////////////////////// + +/* vim:set et sw=2 ts=2: */ === modified file 'src/util/cxx_util.h' --- src/util/cxx_util.h 2012-09-19 21:16:15 +0000 +++ src/util/cxx_util.h 2013-01-15 19:20:28 +0000 @@ -23,13 +23,15 @@ #ifndef ZORBA_CXX_NULLPTR +namespace zorba { + /** - * See: http://www2.research.att.com/~bs/C++0xFAQ.html#nullptr + * A \c nullptr type. * - * We use "zorba_nullptr" in combination with a macro to elimimate a - * "identifier 'nullptr' will become a keyword in C++0x" warning. + * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf + * section 1.1: "Alternative #1: A Library Implementation of nullptr," p. 3. */ -class nullptr_t { +class nullptr_type { public: template<typename T> // convertible to any type operator T*() const { // of null non-member @@ -41,7 +43,18 @@ } private: void operator&() const; // whose address can't be taken -} const zorba_nullptr = {}; // and whose name is nullptr +}; + +} // namespace zorba + +/** + * We use "zorba_nullptr" in combination with a macro to elimimate an + * "identifier 'nullptr' will become a keyword in C++0x" warning. + * + * We also use a singleton object since using multiple instances as shown in + * Bjarne's paper has a sligt performance penalty. + */ +extern zorba::nullptr_type const zorba_nullptr; #define nullptr ::zorba_nullptr === modified file 'src/util/string_util.cpp' --- src/util/string_util.cpp 2013-01-11 15:45:59 +0000 +++ src/util/string_util.cpp 2013-01-15 19:20:28 +0000 @@ -56,64 +56,81 @@ /////////////////////////////////////////////////////////////////////////////// -static void check_errno( char const *buf, char const *end ) { - if ( errno == ERANGE ) { - zstring const s( buf, end ); - throw std::range_error( - BUILD_STRING( '"', s, "\": number too big/small" ) - ); - } -} - -static void check_parse_number( char const *buf, char const *end, +static void no_digits( char const *buf ) { + throw std::invalid_argument( BUILD_STRING( '"', buf, "\": no digits" ) ); +} + +static void too_big_or_small( char const *buf, char const *end ) { + zstring const s( buf, end ); + throw std::range_error( BUILD_STRING( '"', s, "\": number too big/small" ) ); +} + +inline void check_errno( char const *buf, char const *end ) { + if ( errno == ERANGE ) + too_big_or_small( buf, end ); +} + +static void check_trailing_chars_impl( char const *end ) { + for ( ; *end; ++end ) // remaining characters, if any, ... + if ( !ascii::is_space( *end ) ) // ... may only be whitespace + throw std::invalid_argument( + BUILD_STRING( '\'', *end, "': invalid character" ) + ); +} + +inline void check_parse_number( char const *buf, char const *end, bool check_trailing_chars ) { if ( end == buf ) - throw std::invalid_argument( BUILD_STRING( '"', buf, "\": no digits" ) ); + no_digits( buf ); if ( check_trailing_chars ) - for ( ; *end; ++end ) // remaining characters, if any, ... - if ( !ascii::is_space( *end ) ) // ... may only be whitespace - throw std::invalid_argument( - BUILD_STRING( '"', *end, "\": invalid character" ) - ); + check_trailing_chars_impl( end ); } -#define ATON_PREAMBLE() \ - bool check_trailing_chars; \ - char const *pc; \ - if ( end ) { \ - check_trailing_chars = false; \ - } else { \ - end = &pc; \ - check_trailing_chars = true; \ - } \ - errno = 0 +class aton_context { +public: + aton_context( char const **&end ) { + if ( end ) { + check_trailing_chars_ = false; + } else { + end = &end_; + check_trailing_chars_ = true; + } + errno = 0; + } + bool check_trailing_chars() const { + return check_trailing_chars_; + } +private: + bool check_trailing_chars_; + char const *end_; +}; /////////////////////////////////////////////////////////////////////////////// double atod( char const *buf, char const **end ) { - ATON_PREAMBLE(); + aton_context const ctx( end ); double const result = std::strtod( buf, (char**)end ); - check_parse_number( buf, *end, check_trailing_chars ); + check_parse_number( buf, *end, ctx.check_trailing_chars() ); return result; } float atof( char const *buf, char const **end ) { - ATON_PREAMBLE(); + aton_context const ctx( end ); float const result = std::strtof( buf, (char**)end ); - check_parse_number( buf, *end, check_trailing_chars ); + check_parse_number( buf, *end, ctx.check_trailing_chars() ); return result; } long long atoll( char const *buf, char const **end ) { - ATON_PREAMBLE(); + aton_context const ctx( end ); long long const result = std::strtoll( buf, (char**)end, 10 ); check_errno( buf, *end ); - check_parse_number( buf, *end, check_trailing_chars ); + check_parse_number( buf, *end, ctx.check_trailing_chars() ); return result; } unsigned long long atoull( char const *buf, char const **end ) { - ATON_PREAMBLE(); + aton_context const ctx( end ); // // We have to check for '-' ourselves since strtoull(3) allows it (oddly). // @@ -122,7 +139,7 @@ unsigned long long const result = std::strtoull( buf, (char**)end, 10 ); check_errno( buf, *end ); - check_parse_number( buf, *end, check_trailing_chars ); + check_parse_number( buf, *end, ctx.check_trailing_chars() ); if ( minus && result ) { //
-- Mailing list: https://launchpad.net/~zorba-coders Post to : [email protected] Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp

