summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2012-05-08 22:50:24 (GMT)
committerNico Weber <thakis@chromium.org>2012-05-08 23:55:27 (GMT)
commit1e9124b09db813c79d22fd19f26c29cd4129b17b (patch)
treed6cdd002f517f5dce39eed090951028d3c08c8be /src
parent3b0e78ae100f1a6d97358a9bd4a5d65280f42904 (diff)
downloadNinja-1e9124b09db813c79d22fd19f26c29cd4129b17b.zip
Ninja-1e9124b09db813c79d22fd19f26c29cd4129b17b.tar.gz
Ninja-1e9124b09db813c79d22fd19f26c29cd4129b17b.tar.bz2
Add a BuildLog loading perftest.
Diffstat (limited to 'src')
-rw-r--r--src/build_log_perftest.cc139
-rw-r--r--src/build_log_test.cc2
2 files changed, 140 insertions, 1 deletions
diff --git a/src/build_log_perftest.cc b/src/build_log_perftest.cc
new file mode 100644
index 0000000..51bb51b
--- /dev/null
+++ b/src/build_log_perftest.cc
@@ -0,0 +1,139 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "build_log.h"
+#include "graph.h"
+#include "parsers.h"
+#include "state.h"
+#include "util.h"
+
+const char kTestFilename[] = "BuildLogPerfTest-tempfile";
+
+bool WriteTestData(string* err) {
+ BuildLog log;
+
+ if (!log.OpenForWrite(kTestFilename, err))
+ return false;
+
+ /*
+ A histogram of command lengths in chromium. For example, 407 builds,
+ 1.4% of all builds, had commands longer than 32 bytes but shorter than 64.
+ 32 407 1.4%
+ 64 183 0.6%
+ 128 1461 5.1%
+ 256 791 2.8%
+ 512 1314 4.6%
+ 1024 6114 21.3%
+ 2048 11759 41.0%
+ 4096 2056 7.2%
+ 8192 4567 15.9%
+ 16384 13 0.0%
+ 32768 4 0.0%
+ 65536 5 0.0%
+ The average command length is 4.1 kB and there were 28674 commands in total,
+ which makes for a total log size of ~120 MB (also counting output filenames).
+
+ Based on this, write 30000 many 4 kB long command lines.
+ */
+
+ // ManifestParser is the only object allowed to create Rules.
+ const size_t kRuleSize = 4000;
+ string long_rule_command = "gcc ";
+ for (int i = 0; long_rule_command.size() < kRuleSize; ++i) {
+ char buf[80];
+ sprintf(buf, "-I../../and/arbitrary/but/fairly/long/path/suffixed/%d ", i);
+ long_rule_command += buf;
+ }
+ long_rule_command += "$in -o $out\n";
+
+ State state;
+ ManifestParser parser(&state, NULL);
+ if (!parser.ParseTest("rule cxx\n command = " + long_rule_command, err))
+ return false;
+
+ // Create build edges. Using ManifestParser is as fast as using the State api
+ // for edge creation, so just use that.
+ const int kNumCommands = 30000;
+ string build_rules;
+ for (int i = 0; i < kNumCommands; ++i) {
+ char buf[80];
+ sprintf(buf, "build input%d.o: cxx input%d.cc\n", i, i);
+ build_rules += buf;
+ }
+
+ if (!parser.ParseTest(build_rules, err))
+ return false;
+
+ for (int i = 0; i < kNumCommands; ++i) {
+ log.RecordCommand(state.edges_[i],
+ /*start_time=*/100 * i,
+ /*end_time=*/100 * i + 1,
+ /*restat_mtime=*/0);
+ }
+
+ return true;
+}
+
+int main() {
+ vector<int> times;
+ string err;
+
+ if (!WriteTestData(&err)) {
+ fprintf(stderr, "Failed to write test data: %s\n", err.c_str());
+ return 1;
+ }
+
+ {
+ // Read once to warm up disk cache.
+ BuildLog log;
+ if (!log.Load(kTestFilename, &err)) {
+ fprintf(stderr, "Failed to read test data: %s\n", err.c_str());
+ return 1;
+ }
+ }
+ const int kNumRepetitions = 5;
+ for (int i = 0; i < kNumRepetitions; ++i) {
+ int64_t start = GetTimeMillis();
+ BuildLog log;
+ if (!log.Load(kTestFilename, &err)) {
+ fprintf(stderr, "Failed to read test data: %s\n", err.c_str());
+ return 1;
+ }
+ int delta = (int)(GetTimeMillis() - start);
+ printf("%dms\n", delta);
+ times.push_back(delta);
+ }
+
+ int min = times[0];
+ int max = times[0];
+ float total = 0;
+ for (size_t i = 0; i < times.size(); ++i) {
+ total += times[i];
+ if (times[i] < min)
+ min = times[i];
+ else if (times[i] > max)
+ max = times[i];
+ }
+
+ printf("min %dms max %dms avg %.1fms\n",
+ min, max, total / times.size());
+
+ unlink(kTestFilename);
+
+ return 0;
+}
+
diff --git a/src/build_log_test.cc b/src/build_log_test.cc
index 08c3083..84a4ca5 100644
--- a/src/build_log_test.cc
+++ b/src/build_log_test.cc
@@ -28,7 +28,7 @@
#include <unistd.h>
#endif
-static const char kTestFilename[] = "BuildLogTest-tempfile";
+const char kTestFilename[] = "BuildLogTest-tempfile";
struct BuildLogTest : public StateTestWithBuiltinRules {
virtual void SetUp() {