aboutsummaryrefslogtreecommitdiff
path: root/src/internal.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-12-07 02:22:20 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-12-07 18:22:28 +0100
commit263b259b276edd075b0abcd6aad0e923230c2d15 (patch)
tree9d58da6d9cbffd0b9f17ed1c46ea2a51ceb8a400 /src/internal.cpp
parentcae698abe380b3823c3f08151c25097031ae091f (diff)
downloadPROJ-263b259b276edd075b0abcd6aad0e923230c2d15.tar.gz
PROJ-263b259b276edd075b0abcd6aad0e923230c2d15.zip
Various speed optimizations
Diffstat (limited to 'src/internal.cpp')
-rw-r--r--src/internal.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/internal.cpp b/src/internal.cpp
index 4bec1bf9..ecb724c2 100644
--- a/src/internal.cpp
+++ b/src/internal.cpp
@@ -32,6 +32,7 @@
#include "proj/internal/internal.hpp"
+#include <cstdint>
#include <cstring>
#ifdef _MSC_VER
#include <string.h>
@@ -237,6 +238,38 @@ bool ends_with(const std::string &str, const std::string &suffix) noexcept {
// ---------------------------------------------------------------------------
double c_locale_stod(const std::string &s) {
+
+ const auto s_size = s.size();
+ // Fast path
+ if (s_size > 0 && s_size < 15) {
+ std::int64_t acc = 0;
+ std::int64_t div = 1;
+ bool afterDot = false;
+ size_t i = 0;
+ if (s[0] == '-') {
+ ++i;
+ div = -1;
+ } else if (s[0] == '+') {
+ ++i;
+ }
+ for (; i < s_size; ++i) {
+ const auto ch = s[i];
+ if (ch >= '0' && ch <= '9') {
+ acc = acc * 10 + ch - '0';
+ if (afterDot) {
+ div *= 10;
+ }
+ } else if (ch == '.') {
+ afterDot = true;
+ } else {
+ div = 0;
+ }
+ }
+ if (div) {
+ return static_cast<double>(acc) / div;
+ }
+ }
+
std::istringstream iss(s);
iss.imbue(std::locale::classic());
double d;