json_perftest.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/json/json_reader.h"
  5. #include "base/json/json_writer.h"
  6. #include "base/memory/ptr_util.h"
  7. #include "base/strings/string_number_conversions.h"
  8. #include "base/time/time.h"
  9. #include "base/values.h"
  10. #include "build/build_config.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "testing/perf/perf_result_reporter.h"
  13. namespace base {
  14. namespace {
  15. constexpr char kMetricPrefixJSON[] = "JSON.";
  16. constexpr char kMetricReadTime[] = "read_time";
  17. constexpr char kMetricWriteTime[] = "write_time";
  18. perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) {
  19. perf_test::PerfResultReporter reporter(kMetricPrefixJSON, story_name);
  20. reporter.RegisterImportantMetric(kMetricReadTime, "ms");
  21. reporter.RegisterImportantMetric(kMetricWriteTime, "ms");
  22. return reporter;
  23. }
  24. // Generates a simple dictionary value with simple data types, a string and a
  25. // list.
  26. Value::Dict GenerateDict() {
  27. Value::Dict root;
  28. root.Set("Double", 3.141);
  29. root.Set("Bool", true);
  30. root.Set("Int", 42);
  31. root.Set("String", "Foo");
  32. Value::List list;
  33. list.Append(2.718);
  34. list.Append(false);
  35. list.Append(123);
  36. list.Append("Bar");
  37. root.Set("List", std::move(list));
  38. return root;
  39. }
  40. // Generates a tree-like dictionary value with a size of O(breadth ** depth).
  41. Value::Dict GenerateLayeredDict(int breadth, int depth) {
  42. if (depth == 1)
  43. return GenerateDict();
  44. Value::Dict root = GenerateDict();
  45. Value::Dict next = GenerateLayeredDict(breadth, depth - 1);
  46. for (int i = 0; i < breadth; ++i) {
  47. root.Set("Dict" + base::NumberToString(i), next.Clone());
  48. }
  49. return root;
  50. }
  51. } // namespace
  52. class JSONPerfTest : public testing::Test {
  53. public:
  54. void TestWriteAndRead(int breadth, int depth) {
  55. std::string description = "Breadth: " + base::NumberToString(breadth) +
  56. ", Depth: " + base::NumberToString(depth);
  57. Value::Dict dict = GenerateLayeredDict(breadth, depth);
  58. std::string json;
  59. TimeTicks start_write = TimeTicks::Now();
  60. JSONWriter::Write(dict, &json);
  61. TimeTicks end_write = TimeTicks::Now();
  62. auto reporter = SetUpReporter("breadth_" + base::NumberToString(breadth) +
  63. "_depth_" + base::NumberToString(depth));
  64. reporter.AddResult(kMetricWriteTime, end_write - start_write);
  65. TimeTicks start_read = TimeTicks::Now();
  66. JSONReader::Read(json);
  67. TimeTicks end_read = TimeTicks::Now();
  68. reporter.AddResult(kMetricReadTime, end_read - start_read);
  69. }
  70. };
  71. TEST_F(JSONPerfTest, StressTest) {
  72. // These loop ranges are chosen such that this test will complete in a
  73. // reasonable amount of time and will work on a 32-bit build without hitting
  74. // an out-of-memory failure. Having j go to 10 uses over 2 GiB of memory and
  75. // might hit Android timeouts so be wary of going that high.
  76. for (int i = 0; i < 4; ++i) {
  77. for (int j = 0; j < 10; ++j) {
  78. TestWriteAndRead(i + 1, j + 1);
  79. }
  80. }
  81. }
  82. } // namespace base