From a7edcfb533f34ffcb1fe0440e856f0966fb6b008 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Thu, 25 Apr 2019 12:51:42 +0000 Subject: [Support] Add JSON streaming output API, faster where the heavy value types aren't needed. Summary: There's still a little bit of constant factor that could be trimmed (e.g. more overloads to avoid round-tripping primitives through json::Value). But this solves the memory scaling problem, and greatly improves the performance constant factor, and the API should leave room for optimization if needed. Adapt TimeProfiler to use it, eliminating almost all the performance regression from r358476. Performance test on my machine: perf stat -r 5 ~/llvmbuild-opt/bin/clang++ -w -S -ftime-trace -mllvm -time-trace-granularity=0 spirit.cpp Handcrafted JSON (HEAD=r358532 with r358476 reverted): 2480ms json::Value (HEAD): 2757ms (+11%) After this patch: 2520 ms (+1.6%) Reviewers: anton-afanasyev, lebedev.ri Subscribers: kristina, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60804 llvm-svn: 359186 --- llvm/unittests/Support/JSONTest.cpp | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'llvm/unittests') diff --git a/llvm/unittests/Support/JSONTest.cpp b/llvm/unittests/Support/JSONTest.cpp index 23645b35f43..14c11b1c4ed 100644 --- a/llvm/unittests/Support/JSONTest.cpp +++ b/llvm/unittests/Support/JSONTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/JSON.h" +#include "llvm/Support/raw_ostream.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -383,6 +384,44 @@ TEST(JSONTest, Deserialize) { << "Wrong type for Optional " << V; } +TEST(JSONTest, Stream) { + auto StreamStuff = [](unsigned Indent) { + std::string S; + llvm::raw_string_ostream OS(S); + OStream J(OS, Indent); + J.object([&] { + J.attributeArray("foo", [&] { + J.value(nullptr); + J.value(42.5); + J.arrayBegin(); + J.value(43); + J.arrayEnd(); + }); + J.attributeBegin("bar"); + J.objectBegin(); + J.objectEnd(); + J.attributeEnd(); + J.attribute("baz", "xyz"); + }); + return OS.str(); + }; + + const char *Plain = R"({"foo":[null,42.5,[43]],"bar":{},"baz":"xyz"})"; + EXPECT_EQ(Plain, StreamStuff(0)); + const char *Pretty = R"({ + "foo": [ + null, + 42.5, + [ + 43 + ] + ], + "bar": {}, + "baz": "xyz" +})"; + EXPECT_EQ(Pretty, StreamStuff(2)); +} + } // namespace } // namespace json } // namespace llvm -- cgit v1.2.3