null-eval.c++ (4371B)
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 "null-common.h" 23 24 namespace capnp { 25 namespace benchmark { 26 namespace null { 27 28 enum class Operation { 29 ADD, 30 SUBTRACT, 31 MULTIPLY, 32 DIVIDE, 33 MODULUS 34 }; 35 uint OPERATION_RANGE = static_cast<uint>(Operation::MODULUS) + 1; 36 37 struct Expression { 38 Operation op; 39 40 bool leftIsValue; 41 bool rightIsValue; 42 43 union { 44 int32_t leftValue; 45 Expression* leftExpression; 46 }; 47 48 union { 49 int32_t rightValue; 50 Expression* rightExpression; 51 }; 52 }; 53 54 int32_t makeExpression(Expression* exp, uint depth) { 55 exp->op = (Operation)(fastRand(OPERATION_RANGE)); 56 57 int32_t left, right; 58 59 if (fastRand(8) < depth) { 60 exp->leftIsValue = true; 61 left = fastRand(128) + 1; 62 exp->leftValue = left; 63 } else { 64 exp->leftIsValue = false; 65 exp->leftExpression = allocate<Expression>(); 66 left = makeExpression(exp->leftExpression, depth + 1); 67 } 68 69 if (fastRand(8) < depth) { 70 exp->rightIsValue = true; 71 right = fastRand(128) + 1; 72 exp->rightValue = right; 73 } else { 74 exp->rightIsValue = false; 75 exp->rightExpression = allocate<Expression>(); 76 right = makeExpression(exp->rightExpression, depth + 1); 77 } 78 79 switch (exp->op) { 80 case Operation::ADD: 81 return left + right; 82 case Operation::SUBTRACT: 83 return left - right; 84 case Operation::MULTIPLY: 85 return left * right; 86 case Operation::DIVIDE: 87 return div(left, right); 88 case Operation::MODULUS: 89 return mod(left, right); 90 } 91 throw std::logic_error("Can't get here."); 92 } 93 94 int32_t evaluateExpression(const Expression& exp) { 95 uint32_t left, right; 96 97 if (exp.leftIsValue) { 98 left = exp.leftValue; 99 } else { 100 left = evaluateExpression(*exp.leftExpression); 101 } 102 103 if (exp.rightIsValue) { 104 right = exp.rightValue; 105 } else { 106 right = evaluateExpression(*exp.rightExpression); 107 } 108 109 switch (exp.op) { 110 case Operation::ADD: 111 return left + right; 112 case Operation::SUBTRACT: 113 return left - right; 114 case Operation::MULTIPLY: 115 return left * right; 116 case Operation::DIVIDE: 117 return div(left, right); 118 case Operation::MODULUS: 119 return mod(left, right); 120 } 121 throw std::logic_error("Can't get here."); 122 } 123 124 class ExpressionTestCase { 125 public: 126 typedef Expression Request; 127 typedef int32_t Response; 128 typedef int32_t Expectation; 129 130 static inline int32_t setupRequest(Expression* request) { 131 return makeExpression(request, 0); 132 } 133 static inline void handleRequest(const Expression& request, int32_t* response) { 134 *response = evaluateExpression(request); 135 } 136 static inline bool checkResponse(int32_t response, int32_t expected) { 137 return response == expected; 138 } 139 140 static size_t spaceUsed(const Expression& expression) { 141 return sizeof(Expression) + 142 (expression.leftExpression == nullptr ? 0 : spaceUsed(*expression.leftExpression)) + 143 (expression.rightExpression == nullptr ? 0 : spaceUsed(*expression.rightExpression)); 144 } 145 }; 146 147 } // namespace null 148 } // namespace benchmark 149 } // namespace capnp 150 151 int main(int argc, char* argv[]) { 152 return capnp::benchmark::benchmarkMain< 153 capnp::benchmark::null::BenchmarkTypes, 154 capnp::benchmark::null::ExpressionTestCase>(argc, argv); 155 }