193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//===- YAMLBench - Benchmark the YAMLParser implementation ----------------===// 293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// 393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// The LLVM Compiler Infrastructure 493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// 593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// This file is distributed under the University of Illinois Open Source 693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// License. See LICENSE.TXT for details. 793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// 893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//===----------------------------------------------------------------------===// 993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// 1093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// This program executes the YAMLParser on differntly sized YAML texts and 1193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// outputs the run time. 1293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer// 1393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer//===----------------------------------------------------------------------===// 1493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 1593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 1693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/ADT/SmallString.h" 1793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/Casting.h" 1893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/CommandLine.h" 1993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/MemoryBuffer.h" 2093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/raw_ostream.h" 2193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/SourceMgr.h" 2293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/system_error.h" 2393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/Timer.h" 2493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/YAMLParser.h" 2593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 2693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerusing namespace llvm; 2793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 2893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic cl::opt<bool> 2993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer DumpTokens( "tokens" 3093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , cl::desc("Print the tokenization of the file.") 3193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , cl::init(false) 3293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ); 3393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 3493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic cl::opt<bool> 3593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer DumpCanonical( "canonical" 3693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , cl::desc("Print the canonical YAML for this file.") 3793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , cl::init(false) 3893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ); 3993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 4093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic cl::opt<std::string> 4193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Input(cl::Positional, cl::desc("<input>")); 4293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 4393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic cl::opt<bool> 4493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Verify( "verify" 4593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , cl::desc( 4693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer "Run a quick verification useful for regression testing") 4793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , cl::init(false) 4893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ); 4993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 5093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic cl::opt<unsigned> 5193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer MemoryLimitMB("memory-limit", cl::desc( 5293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer "Do not use more megabytes of memory"), 5393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer cl::init(1000)); 5493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 5593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstruct indent { 5693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer unsigned distance; 5793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer indent(unsigned d) : distance(d) {} 5893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer}; 5993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 6093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic raw_ostream &operator <<(raw_ostream &os, const indent &in) { 6193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (unsigned i = 0; i < in.distance; ++i) 6293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer os << " "; 6393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return os; 6493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 6593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 6693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void dumpNode( yaml::Node *n 6793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , unsigned Indent = 0 6893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , bool SuppressFirstIndent = false) { 6993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (!n) 7093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return; 7193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (!SuppressFirstIndent) 7293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent); 7393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer StringRef Anchor = n->getAnchor(); 7493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (!Anchor.empty()) 7593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "&" << Anchor << " "; 7693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (yaml::ScalarNode *sn = dyn_cast<yaml::ScalarNode>(n)) { 7793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer SmallString<32> Storage; 7893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer StringRef Val = sn->getValue(Storage); 7993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "!!str \"" << yaml::escape(Val) << "\""; 8093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (yaml::SequenceNode *sn = dyn_cast<yaml::SequenceNode>(n)) { 8193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "!!seq [\n"; 8293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ++Indent; 8393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (yaml::SequenceNode::iterator i = sn->begin(), e = sn->end(); 8493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer i != e; ++i) { 8593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(i, Indent); 8693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << ",\n"; 8793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 8893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer --Indent; 8993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << "]"; 9093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (yaml::MappingNode *mn = dyn_cast<yaml::MappingNode>(n)) { 9193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "!!map {\n"; 9293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ++Indent; 9393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (yaml::MappingNode::iterator i = mn->begin(), e = mn->end(); 9493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer i != e; ++i) { 9593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << "? "; 9693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(i->getKey(), Indent, true); 9793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "\n"; 9893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << ": "; 9993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(i->getValue(), Indent, true); 10093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << ",\n"; 10193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 10293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer --Indent; 10393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << "}"; 10493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (yaml::AliasNode *an = dyn_cast<yaml::AliasNode>(n)){ 10593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "*" << an->getName(); 10693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (dyn_cast<yaml::NullNode>(n)) { 10793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "!!null null"; 10893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 10993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 11093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 11193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void dumpStream(yaml::Stream &stream) { 11293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (yaml::document_iterator di = stream.begin(), de = stream.end(); di != de; 11393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ++di) { 11493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "%YAML 1.2\n" 11593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << "---\n"; 11693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer yaml::Node *n = di->getRoot(); 11793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (n) 11893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(n); 11993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer else 12093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer break; 12193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "\n...\n"; 12293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 12393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 12493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 12593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void benchmark( llvm::TimerGroup &Group 12693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , llvm::StringRef Name 12793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , llvm::StringRef JSONText) { 12893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::Timer BaseLine((Name + ": Loop").str(), Group); 12993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer BaseLine.startTimer(); 13093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer char C = 0; 13193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (llvm::StringRef::iterator I = JSONText.begin(), 13293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer E = JSONText.end(); 13393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer I != E; ++I) { C += *I; } 13493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer BaseLine.stopTimer(); 13593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer volatile char DontOptimizeOut = C; (void)DontOptimizeOut; 13693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 13793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::Timer Tokenizing((Name + ": Tokenizing").str(), Group); 13893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Tokenizing.startTimer(); 13993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer { 14093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer yaml::scanTokens(JSONText); 14193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 14293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Tokenizing.stopTimer(); 14393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 14493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::Timer Parsing((Name + ": Parsing").str(), Group); 14593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Parsing.startTimer(); 14693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer { 14793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::SourceMgr SM; 14893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::yaml::Stream stream(JSONText, SM); 14993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer stream.skip(); 15093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 15193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Parsing.stopTimer(); 15293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 15393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 15493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic std::string createJSONText(size_t MemoryMB, unsigned ValueSize) { 15593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer std::string JSONText; 15693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::raw_string_ostream Stream(JSONText); 15793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << "[\n"; 15893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer size_t MemoryBytes = MemoryMB * 1024 * 1024; 15993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer while (JSONText.size() < MemoryBytes) { 16093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << " {\n" 16193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " \"key1\": \"" << std::string(ValueSize, '*') << "\",\n" 16293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " \"key2\": \"" << std::string(ValueSize, '*') << "\",\n" 16393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " \"key3\": \"" << std::string(ValueSize, '*') << "\"\n" 16493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " }"; 16593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream.flush(); 16693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (JSONText.size() < MemoryBytes) Stream << ","; 16793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << "\n"; 16893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 16993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << "]\n"; 17093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream.flush(); 17193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return JSONText; 17293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 17393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 17493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerint main(int argc, char **argv) { 17593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::cl::ParseCommandLineOptions(argc, argv); 17693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (Input.getNumOccurrences()) { 17793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer OwningPtr<MemoryBuffer> Buf; 17893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) 17993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return 1; 18093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 18193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::SourceMgr sm; 18293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (DumpTokens) { 18393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer yaml::dumpTokens(Buf->getBuffer(), outs()); 18493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 18593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 18693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (DumpCanonical) { 18793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer yaml::Stream stream(Buf->getBuffer(), sm); 18893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpStream(stream); 18993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 19093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 19193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 19293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (Verify) { 19393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::TimerGroup Group("YAML parser benchmark"); 19493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Fast", createJSONText(10, 500)); 19593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (!DumpCanonical && !DumpTokens) { 19693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::TimerGroup Group("YAML parser benchmark"); 19793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Small Values", createJSONText(MemoryLimitMB, 5)); 19893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Medium Values", createJSONText(MemoryLimitMB, 500)); 19993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Large Values", createJSONText(MemoryLimitMB, 50000)); 20093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 20193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 20293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return 0; 20393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 204