From b449b22abcceddab154e1694eb4f8ca8e392e35f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Thu, 4 Dec 2014 12:59:09 +0100 Subject: [PATCH] remove use of std::to_string in favor of boost::lexical_cast std::to_string calls sprintf() internally, which is really slow --- include/mbgl/map/tile.hpp | 5 +---- include/mbgl/util/string.hpp | 18 ++++++++++++++++++ platform/default/glfw_view.cpp | 2 -- src/geometry/vao.cpp | 5 +++-- src/map/source.cpp | 4 ++-- src/map/tile.cpp | 7 +++++++ src/map/tile_data.cpp | 10 +++++----- src/renderer/painter_debug.cpp | 2 +- src/style/value.cpp | 14 ++++---------- src/text/glyph_store.cpp | 4 ++-- src/util/stopwatch.cpp | 3 ++- 11 files changed, 45 insertions(+), 29 deletions(-) diff --git a/include/mbgl/map/tile.hpp b/include/mbgl/map/tile.hpp index 1ae13dd79..bdb127030 100644 --- a/include/mbgl/map/tile.hpp +++ b/include/mbgl/map/tile.hpp @@ -44,10 +44,6 @@ public: return ((std::pow(2, z) * y + x) * 32) + z; } - inline operator std::string() const { - return std::to_string(z) + "/" + std::to_string(x) + "/" + std::to_string(y); - } - inline bool operator==(const ID& rhs) const { return w == rhs.w && z == rhs.z && x == rhs.x && y == rhs.y; } @@ -67,6 +63,7 @@ public: ID normalized() const; std::forward_list children(int32_t z) const; bool isChildOf(const Tile::ID &id) const; + operator std::string() const; }; static std::forward_list cover(int8_t z, const box& bounds); diff --git a/include/mbgl/util/string.hpp b/include/mbgl/util/string.hpp index f17d55cec..690a67d47 100644 --- a/include/mbgl/util/string.hpp +++ b/include/mbgl/util/string.hpp @@ -3,9 +3,27 @@ #include +#pragma GCC diagnostic push +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif +#include +#pragma GCC diagnostic pop + namespace mbgl { namespace util { +template +inline std::string toString(Args&&... args) { + return boost::lexical_cast(::std::forward(args)...); +} + +// boost::lexical_cast() treats this as a character, but we are using it as number types. +inline std::string toString(int8_t num) { + return boost::lexical_cast(int(num)); +} + + template inline std::string sprintf(const char *msg, Args... args) { char res[max]; diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index 4ddcd9019..d9248f76d 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -1,8 +1,6 @@ #include #include -#include - GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) { #ifdef NVIDIA glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)glfwGetProcAddress("glDiscardFramebufferEXT"); diff --git a/src/geometry/vao.cpp b/src/geometry/vao.cpp index d2fd2727e..66822ba5c 100644 --- a/src/geometry/vao.cpp +++ b/src/geometry/vao.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace mbgl { @@ -31,8 +32,8 @@ void VertexArrayObject::verifyBinding(Shader &shader, GLuint vertexBuffer, GLuin char *offset) { if (bound_shader != shader.getID()) { throw std::runtime_error(std::string("trying to rebind VAO to another shader from " + - std::to_string(bound_shader) + "(" + bound_shader_name + ") to " + - std::to_string(shader.getID()) + "(" + shader.name + ")" )); + util::toString(bound_shader) + "(" + bound_shader_name + ") to " + + util::toString(shader.getID()) + "(" + shader.name + ")" )); } else if (bound_offset != offset) { throw std::runtime_error("trying to bind VAO to another offset"); } else if (bound_vertex_buffer != vertexBuffer) { diff --git a/src/map/source.cpp b/src/map/source.cpp index 35f507286..f4f5a1b81 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -88,13 +88,13 @@ size_t Source::getTileCount() const { void Source::drawClippingMasks(Painter &painter) { for (std::pair> &pair : tiles) { Tile &tile = *pair.second; - gl::group group(util::sprintf<32>("mask %d/%d/%d", tile.id.z, tile.id.y, tile.id.z)); + gl::group group(std::string { "mask: " } + std::string(tile.id)); painter.drawClippingMask(tile.matrix, tile.clip); } } void Source::render(Painter &painter, util::ptr layer_desc) { - gl::group group(std::string("layer: ") + layer_desc->id); + gl::group group(std::string { "layer: " } + layer_desc->id); for (const std::pair> &pair : tiles) { Tile &tile = *pair.second; if (tile.data && tile.data->state == TileData::State::parsed) { diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 3070d3fd9..52f353841 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -1,5 +1,7 @@ #include #include +#include + #include @@ -52,6 +54,11 @@ bool Tile::ID::isChildOf(const Tile::ID &parent_id) const { } +Tile::ID::operator std::string() const { + return util::toString(z) + "/" + util::toString(x) + "/" + util::toString(y); +} + + // Taken from polymaps src/Layer.js // https://github.com/simplegeo/polymaps/blob/master/src/Layer.js#L333-L383 diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 5eed22c47..f89ff15ba 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -11,7 +11,7 @@ using namespace mbgl; TileData::TileData(Tile::ID const& id_, const SourceInfo& source_) : id(id_), - name(util::sprintf<32>("%d/%d/%d", id.z, id.x, id.y)), + name(id), state(State::initial), source(source_), debugBucket(debugFontBuffer) { @@ -24,7 +24,7 @@ TileData::~TileData() { } const std::string TileData::toString() const { - return util::sprintf<32>("[tile %d/%d/%d]", id.z, id.x, id.y); + return std::string { "[tile " } + name + "]"; } void TileData::request(uv::worker& worker, FileSource& fileSource, @@ -34,9 +34,9 @@ void TileData::request(uv::worker& worker, FileSource& fileSource, std::string url = source.tiles[(id.x + id.y) % source.tiles.size()]; url = util::replaceTokens(url, [&](const std::string &token) -> std::string { - if (token == "z") return std::to_string(id.z); - if (token == "x") return std::to_string(id.x); - if (token == "y") return std::to_string(id.y); + if (token == "z") return util::toString(id.z); + if (token == "x") return util::toString(id.x); + if (token == "y") return util::toString(id.y); if (token == "prefix") { std::string prefix { 2 }; prefix[0] = "0123456789abcdef"[id.x % 16]; diff --git a/src/renderer/painter_debug.cpp b/src/renderer/painter_debug.cpp index 5bc36a233..c4d273aa4 100644 --- a/src/renderer/painter_debug.cpp +++ b/src/renderer/painter_debug.cpp @@ -6,7 +6,7 @@ using namespace mbgl; void Painter::renderTileDebug(const Tile& tile) { - gl::group group(util::sprintf<32>("debug %d/%d/%d", tile.id.z, tile.id.y, tile.id.z)); + gl::group group(std::string { "debug " } + std::string(tile.id)); assert(tile.data); if (debug) { prepareTile(tile); diff --git a/src/style/value.cpp b/src/style/value.cpp index bda9a089a..ae51ce378 100644 --- a/src/style/value.cpp +++ b/src/style/value.cpp @@ -1,11 +1,5 @@ #include - -#pragma GCC diagnostic push -#ifndef __clang__ -#pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#endif -#include -#pragma GCC diagnostic pop +#include mbgl::Value mbgl::parseValue(pbf data) { while (data.next()) @@ -37,9 +31,9 @@ mbgl::Value mbgl::parseValue(pbf data) { std::string mbgl::toString(const mbgl::Value& value) { if (value.is()) return value.get(); else if (value.is()) return value.get() ? "true" : "false"; - else if (value.is()) return std::to_string(value.get()); - else if (value.is()) return std::to_string(value.get()); - else if (value.is()) return boost::lexical_cast(value.get()); + else if (value.is()) return util::toString(value.get()); + else if (value.is()) return util::toString(value.get()); + else if (value.is()) return util::toString(value.get()); else return "null"; } diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp index 8537ab515..2f5db180f 100644 --- a/src/text/glyph_store.cpp +++ b/src/text/glyph_store.cpp @@ -143,7 +143,7 @@ GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, Gl // Load the glyph set URL std::string url = util::replaceTokens(glyphURL, [&](const std::string &name) -> std::string { if (name == "fontstack") return util::percentEncode(fontStack); - if (name == "range") return std::to_string(glyphRange.first) + "-" + std::to_string(glyphRange.second); + if (name == "range") return util::toString(glyphRange.first) + "-" + util::toString(glyphRange.second); return ""; }); @@ -153,7 +153,7 @@ GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, Gl request->onload([&, url](const Response &res) { if (res.code != 200) { // Something went wrong with loading the glyph pbf. Pass on the error to the future listeners. - const std::string msg = util::sprintf<255>("[ERROR] failed to load glyphs (%d): %s\n", res.code, res.message.c_str()); + const std::string msg = std::string { "[ERROR] failed to load glyphs (" } + util::toString(res.code) + "): " + res.message; promise.set_exception(std::make_exception_ptr(std::runtime_error(msg))); } else { // Transfer the data to the GlyphSet and signal its availability. diff --git a/src/util/stopwatch.cpp b/src/util/stopwatch.cpp index c9b8756e3..14b4f4018 100644 --- a/src/util/stopwatch.cpp +++ b/src/util/stopwatch.cpp @@ -1,6 +1,7 @@ #ifndef DISABLE_STOPWATCH #include #include +#include #include #include @@ -23,7 +24,7 @@ stopwatch::stopwatch(const std::string &name_, EventSeverity severity_, Event ev void stopwatch::report(const std::string &name_) { timestamp duration = now() - start; - Log::Record(severity, event, name_ + ": " + std::to_string((double)(duration) / 1_millisecond) + "ms"); + Log::Record(severity, event, name_ + ": " + util::toString(double(duration) / 1_millisecond) + "ms"); start += duration; }