protobuf-eval.c++ (3649B)
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #include "eval.pb.h" 23 #include "protobuf-common.h" 24 25 namespace capnp { 26 namespace benchmark { 27 namespace protobuf { 28 29 int32_t makeExpression(Expression* exp, uint depth) { 30 exp->set_op((Operation)(fastRand(Operation_MAX + 1))); 31 32 int32_t left, right; 33 34 if (fastRand(8) < depth) { 35 left = fastRand(128) + 1; 36 exp->set_left_value(left); 37 } else { 38 left = makeExpression(exp->mutable_left_expression(), depth + 1); 39 } 40 41 if (fastRand(8) < depth) { 42 right = fastRand(128) + 1; 43 exp->set_right_value(right); 44 } else { 45 right = makeExpression(exp->mutable_right_expression(), depth + 1); 46 } 47 48 switch (exp->op()) { 49 case Operation::ADD: 50 return left + right; 51 case Operation::SUBTRACT: 52 return left - right; 53 case Operation::MULTIPLY: 54 return left * right; 55 case Operation::DIVIDE: 56 return div(left, right); 57 case Operation::MODULUS: 58 return mod(left, right); 59 } 60 throw std::logic_error("Can't get here."); 61 } 62 63 int32_t evaluateExpression(const Expression& exp) { 64 uint32_t left, right; 65 66 if (exp.has_left_value()) { 67 left = exp.left_value(); 68 } else { 69 left = evaluateExpression(exp.left_expression()); 70 } 71 72 if (exp.has_right_value()) { 73 right = exp.right_value(); 74 } else { 75 right = evaluateExpression(exp.right_expression()); 76 } 77 78 switch (exp.op()) { 79 case Operation::ADD: 80 return left + right; 81 case Operation::SUBTRACT: 82 return left - right; 83 case Operation::MULTIPLY: 84 return left * right; 85 case Operation::DIVIDE: 86 return div(left, right); 87 case Operation::MODULUS: 88 return mod(left, right); 89 } 90 throw std::logic_error("Can't get here."); 91 } 92 93 class ExpressionTestCase { 94 public: 95 typedef Expression Request; 96 typedef EvaluationResult Response; 97 typedef int32_t Expectation; 98 99 static inline int32_t setupRequest(Expression* request) { 100 return makeExpression(request, 0); 101 } 102 static inline void handleRequest(const Expression& request, EvaluationResult* response) { 103 response->set_value(evaluateExpression(request)); 104 } 105 static inline bool checkResponse(const EvaluationResult& response, int32_t expected) { 106 return response.value() == expected; 107 } 108 }; 109 110 } // namespace protobuf 111 } // namespace benchmark 112 } // namespace capnp 113 114 int main(int argc, char* argv[]) { 115 return capnp::benchmark::benchmarkMain< 116 capnp::benchmark::protobuf::BenchmarkTypes, 117 capnp::benchmark::protobuf::ExpressionTestCase>(argc, argv); 118 }