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// 10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This program executes the YAMLParser on differently 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/SourceMgr.h" 2193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/Timer.h" 2293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer#include "llvm/Support/YAMLParser.h" 234ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/Support/raw_ostream.h" 24c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 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 6644a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer/// \brief Pretty print a tag by replacing tag:yaml.org,2002: with !!. 6744a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencerstatic std::string prettyTag(yaml::Node *N) { 6844a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer std::string Tag = N->getVerbatimTag(); 6944a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer if (StringRef(Tag).startswith("tag:yaml.org,2002:")) { 7044a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer std::string Ret = "!!"; 7144a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer Ret += StringRef(Tag).substr(18); 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return std::move(Ret); 7344a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer } 7444a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer std::string Ret = "!<"; 7544a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer Ret += Tag; 7644a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer Ret += ">"; 7744a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer return Ret; 7844a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer} 7944a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer 8093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void dumpNode( yaml::Node *n 8193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , unsigned Indent = 0 8293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , bool SuppressFirstIndent = false) { 8393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (!n) 8493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return; 8593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (!SuppressFirstIndent) 8693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent); 8793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer StringRef Anchor = n->getAnchor(); 8893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (!Anchor.empty()) 8993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "&" << Anchor << " "; 9093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (yaml::ScalarNode *sn = dyn_cast<yaml::ScalarNode>(n)) { 9193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer SmallString<32> Storage; 9293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer StringRef Val = sn->getValue(Storage); 9344a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer outs() << prettyTag(n) << " \"" << yaml::escape(Val) << "\""; 9493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (yaml::SequenceNode *sn = dyn_cast<yaml::SequenceNode>(n)) { 9544a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer outs() << prettyTag(n) << " [\n"; 9693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ++Indent; 9793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (yaml::SequenceNode::iterator i = sn->begin(), e = sn->end(); 9893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer i != e; ++i) { 9993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(i, Indent); 10093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << ",\n"; 10193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 10293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer --Indent; 10393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << "]"; 10493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (yaml::MappingNode *mn = dyn_cast<yaml::MappingNode>(n)) { 10544a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer outs() << prettyTag(n) << " {\n"; 10693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ++Indent; 10793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (yaml::MappingNode::iterator i = mn->begin(), e = mn->end(); 10893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer i != e; ++i) { 10993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << "? "; 11093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(i->getKey(), Indent, true); 11193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "\n"; 11293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << ": "; 11393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(i->getValue(), Indent, true); 11493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << ",\n"; 11593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 11693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer --Indent; 11793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << indent(Indent) << "}"; 11893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (yaml::AliasNode *an = dyn_cast<yaml::AliasNode>(n)){ 11993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "*" << an->getName(); 1202c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar } else if (isa<yaml::NullNode>(n)) { 12144a4cfb63d87dc0ba778982a1796673ca1513e90Michael J. Spencer outs() << prettyTag(n) << " null"; 12293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 12393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 12493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 12593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void dumpStream(yaml::Stream &stream) { 12693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (yaml::document_iterator di = stream.begin(), de = stream.end(); di != de; 12793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer ++di) { 12893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "%YAML 1.2\n" 12993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << "---\n"; 13093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer yaml::Node *n = di->getRoot(); 13193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (n) 13293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpNode(n); 13393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer else 13493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer break; 13593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer outs() << "\n...\n"; 13693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 13793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 13893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 13993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic void benchmark( llvm::TimerGroup &Group 14093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , llvm::StringRef Name 14193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer , llvm::StringRef JSONText) { 14293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::Timer BaseLine((Name + ": Loop").str(), Group); 14393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer BaseLine.startTimer(); 14493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer char C = 0; 14593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer for (llvm::StringRef::iterator I = JSONText.begin(), 14693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer E = JSONText.end(); 14793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer I != E; ++I) { C += *I; } 14893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer BaseLine.stopTimer(); 14993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer volatile char DontOptimizeOut = C; (void)DontOptimizeOut; 15093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 15193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::Timer Tokenizing((Name + ": Tokenizing").str(), Group); 15293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Tokenizing.startTimer(); 15393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer { 15493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer yaml::scanTokens(JSONText); 15593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 15693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Tokenizing.stopTimer(); 15793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 15893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::Timer Parsing((Name + ": Parsing").str(), Group); 15993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Parsing.startTimer(); 16093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer { 16193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::SourceMgr SM; 16293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::yaml::Stream stream(JSONText, SM); 16393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer stream.skip(); 16493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 16593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Parsing.stopTimer(); 16693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 16793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 16893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerstatic std::string createJSONText(size_t MemoryMB, unsigned ValueSize) { 16993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer std::string JSONText; 17093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::raw_string_ostream Stream(JSONText); 17193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << "[\n"; 17293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer size_t MemoryBytes = MemoryMB * 1024 * 1024; 17393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer while (JSONText.size() < MemoryBytes) { 17493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << " {\n" 17593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " \"key1\": \"" << std::string(ValueSize, '*') << "\",\n" 17693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " \"key2\": \"" << std::string(ValueSize, '*') << "\",\n" 17793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " \"key3\": \"" << std::string(ValueSize, '*') << "\"\n" 17893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer << " }"; 17993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream.flush(); 18093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (JSONText.size() < MemoryBytes) Stream << ","; 18193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << "\n"; 18293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 18393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream << "]\n"; 18493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer Stream.flush(); 18593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return JSONText; 18693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 18793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 18893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencerint main(int argc, char **argv) { 18993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::cl::ParseCommandLineOptions(argc, argv); 19093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (Input.getNumOccurrences()) { 191c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = 192c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines MemoryBuffer::getFileOrSTDIN(Input); 193c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!BufOrErr) 19493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return 1; 19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MemoryBuffer &Buf = *BufOrErr.get(); 19693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 19793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::SourceMgr sm; 19893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (DumpTokens) { 19937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::dumpTokens(Buf.getBuffer(), outs()); 20093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 20193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 20293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (DumpCanonical) { 20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines yaml::Stream stream(Buf.getBuffer(), sm); 20493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer dumpStream(stream); 20593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 20693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 20793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 20893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer if (Verify) { 20993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::TimerGroup Group("YAML parser benchmark"); 21093210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Fast", createJSONText(10, 500)); 21193210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } else if (!DumpCanonical && !DumpTokens) { 21293210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer llvm::TimerGroup Group("YAML parser benchmark"); 21393210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Small Values", createJSONText(MemoryLimitMB, 5)); 21493210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Medium Values", createJSONText(MemoryLimitMB, 500)); 21593210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer benchmark(Group, "Large Values", createJSONText(MemoryLimitMB, 50000)); 21693210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer } 21793210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer 21893210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer return 0; 21993210e847a1496b24cef881723e57c489082dcfeMichael J. Spencer} 220