Implement fast number serialization routines. (#5772)
* Implement ryu algorithm. * Implement integer printing. * Full coverage roundtrip test.
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
/*!
|
||||
* Copyright (c) by Contributors 2019
|
||||
* Copyright (c) by XGBoost Contributors 2019-2020
|
||||
*/
|
||||
#ifndef XGBOOST_JSON_H_
|
||||
#define XGBOOST_JSON_H_
|
||||
|
||||
#include <xgboost/logging.h>
|
||||
#include <xgboost/parameter.h>
|
||||
#include <string>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
namespace xgboost {
|
||||
|
||||
@@ -331,13 +331,7 @@ class Json {
|
||||
static Json Load(StringView str);
|
||||
/*! \brief Pass your own JsonReader. */
|
||||
static Json Load(JsonReader* reader);
|
||||
/*! \brief Dump json into stream. */
|
||||
static void Dump(Json json, std::ostream* stream,
|
||||
bool pretty = ConsoleLogger::ShouldLog(
|
||||
ConsoleLogger::LogVerbosity::kDebug));
|
||||
static void Dump(Json json, std::string* out,
|
||||
bool pretty = ConsoleLogger::ShouldLog(
|
||||
ConsoleLogger::LogVerbosity::kDebug));
|
||||
static void Dump(Json json, std::string* out);
|
||||
|
||||
Json() : ptr_{new JsonNull} {}
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#ifndef XGBOOST_JSON_IO_H_
|
||||
#define XGBOOST_JSON_IO_H_
|
||||
#include <xgboost/json.h>
|
||||
#include <xgboost/base.h>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <cinttypes>
|
||||
@@ -15,20 +17,6 @@
|
||||
#include <locale>
|
||||
|
||||
namespace xgboost {
|
||||
|
||||
template <typename Allocator>
|
||||
class FixedPrecisionStreamContainer : public std::basic_stringstream<
|
||||
char, std::char_traits<char>, Allocator> {
|
||||
public:
|
||||
FixedPrecisionStreamContainer() {
|
||||
this->precision(std::numeric_limits<double>::max_digits10);
|
||||
this->imbue(std::locale("C"));
|
||||
this->setf(std::ios::scientific);
|
||||
}
|
||||
};
|
||||
|
||||
using FixedPrecisionStream = FixedPrecisionStreamContainer<std::allocator<char>>;
|
||||
|
||||
/*
|
||||
* \brief A json reader, currently error checking and utf-8 is not fully supported.
|
||||
*/
|
||||
@@ -45,13 +33,11 @@ class JsonReader {
|
||||
SourceLocation() = default;
|
||||
size_t Pos() const { return pos_; }
|
||||
|
||||
SourceLocation& Forward() {
|
||||
void Forward() {
|
||||
pos_++;
|
||||
return *this;
|
||||
}
|
||||
SourceLocation& Forward(uint32_t n) {
|
||||
void Forward(uint32_t n) {
|
||||
pos_ += n;
|
||||
return *this;
|
||||
}
|
||||
} cursor_;
|
||||
|
||||
@@ -77,14 +63,17 @@ class JsonReader {
|
||||
return ch;
|
||||
}
|
||||
|
||||
/* \brief Skip spaces and consume next character. */
|
||||
char GetNextNonSpaceChar() {
|
||||
SkipSpaces();
|
||||
return GetNextChar();
|
||||
}
|
||||
|
||||
char GetChar(char c) {
|
||||
char result = GetNextNonSpaceChar();
|
||||
if (result != c) { Expect(c, result); }
|
||||
/* \brief Consume next character without first skipping empty space, throw when the next
|
||||
* character is not the expected one.
|
||||
*/
|
||||
char GetConsecutiveChar(char expected_char) {
|
||||
char result = GetNextChar();
|
||||
if (XGBOOST_EXPECT(result != expected_char, false)) { Expect(expected_char, result); }
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -95,7 +84,11 @@ class JsonReader {
|
||||
std::string msg = "Expecting: \"";
|
||||
msg += c;
|
||||
msg += "\", got: \"";
|
||||
msg += std::string {got} + " \"";
|
||||
if (got == -1) {
|
||||
msg += "EOF\"";
|
||||
} else {
|
||||
msg += std::to_string(got) + " \"";
|
||||
}
|
||||
Error(msg);
|
||||
}
|
||||
|
||||
@@ -119,38 +112,16 @@ class JsonReader {
|
||||
|
||||
class JsonWriter {
|
||||
static constexpr size_t kIndentSize = 2;
|
||||
FixedPrecisionStream convertor_;
|
||||
|
||||
size_t n_spaces_;
|
||||
std::ostream* stream_;
|
||||
bool pretty_;
|
||||
std::vector<char>* stream_;
|
||||
|
||||
public:
|
||||
JsonWriter(std::ostream* stream, bool pretty) :
|
||||
n_spaces_{0}, stream_{stream}, pretty_{pretty} {}
|
||||
explicit JsonWriter(std::vector<char>* stream) :
|
||||
n_spaces_{0}, stream_{stream} {}
|
||||
|
||||
virtual ~JsonWriter() = default;
|
||||
|
||||
void NewLine() {
|
||||
if (pretty_) {
|
||||
*stream_ << u8"\n" << std::string(n_spaces_, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
void BeginIndent() {
|
||||
n_spaces_ += kIndentSize;
|
||||
}
|
||||
void EndIndent() {
|
||||
n_spaces_ -= kIndentSize;
|
||||
}
|
||||
|
||||
void Write(std::string str) {
|
||||
*stream_ << str;
|
||||
}
|
||||
void Write(StringView str) {
|
||||
stream_->write(str.c_str(), str.size());
|
||||
}
|
||||
|
||||
void Save(Json json);
|
||||
|
||||
virtual void Visit(JsonArray const* arr);
|
||||
|
||||
Reference in New Issue
Block a user