protobuf-carsales.c++ (4642B)
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 "carsales.pb.h" 23 #include "protobuf-common.h" 24 25 namespace capnp { 26 namespace benchmark { 27 namespace protobuf { 28 29 uint64_t carValue(const Car& car) { 30 // Do not think too hard about realism. 31 32 uint64_t result = 0; 33 34 result += car.seats() * 200; 35 result += car.doors() * 350; 36 for (auto& wheel: car.wheel()) { 37 result += wheel.diameter() * wheel.diameter(); 38 result += wheel.snow_tires() ? 100 : 0; 39 } 40 41 result += car.length() * car.width() * car.height() / 50; 42 43 const Engine& engine = car.engine(); 44 result += engine.horsepower() * 40; 45 if (engine.uses_electric()) { 46 if (engine.uses_gas()) { 47 // hybrid 48 result += 5000; 49 } else { 50 result += 3000; 51 } 52 } 53 54 result += car.has_power_windows() ? 100 : 0; 55 result += car.has_power_steering() ? 200 : 0; 56 result += car.has_cruise_control() ? 400 : 0; 57 result += car.has_nav_system() ? 2000 : 0; 58 59 result += car.cup_holders() * 25; 60 61 return result; 62 } 63 64 void randomCar(Car* car) { 65 // Do not think too hard about realism. 66 67 static const char* const MAKES[] = { "Toyota", "GM", "Ford", "Honda", "Tesla" }; 68 static const char* const MODELS[] = { "Camry", "Prius", "Volt", "Accord", "Leaf", "Model S" }; 69 70 car->set_make(MAKES[fastRand(sizeof(MAKES) / sizeof(MAKES[0]))]); 71 car->set_model(MODELS[fastRand(sizeof(MODELS) / sizeof(MODELS[0]))]); 72 73 car->set_color((Color)fastRand(Color_MAX)); 74 car->set_seats(2 + fastRand(6)); 75 car->set_doors(2 + fastRand(3)); 76 77 for (uint i = 0; i < 4; i++) { 78 Wheel* wheel = car->add_wheel(); 79 wheel->set_diameter(25 + fastRand(15)); 80 wheel->set_air_pressure(30 + fastRandDouble(20)); 81 wheel->set_snow_tires(fastRand(16) == 0); 82 } 83 84 car->set_length(170 + fastRand(150)); 85 car->set_width(48 + fastRand(36)); 86 car->set_height(54 + fastRand(48)); 87 car->set_weight(car->length() * car->width() * car->height() / 200); 88 89 Engine* engine = car->mutable_engine(); 90 engine->set_horsepower(100 * fastRand(400)); 91 engine->set_cylinders(4 + 2 * fastRand(3)); 92 engine->set_cc(800 + fastRand(10000)); 93 engine->set_uses_gas(true); 94 engine->set_uses_electric(fastRand(2)); 95 96 car->set_fuel_capacity(10.0 + fastRandDouble(30.0)); 97 car->set_fuel_level(fastRandDouble(car->fuel_capacity())); 98 car->set_has_power_windows(fastRand(2)); 99 car->set_has_power_steering(fastRand(2)); 100 car->set_has_cruise_control(fastRand(2)); 101 car->set_cup_holders(fastRand(12)); 102 car->set_has_nav_system(fastRand(2)); 103 } 104 105 class CarSalesTestCase { 106 public: 107 typedef ParkingLot Request; 108 typedef TotalValue Response; 109 typedef uint64_t Expectation; 110 111 static uint64_t setupRequest(ParkingLot* request) { 112 uint count = fastRand(200); 113 uint64_t result = 0; 114 for (uint i = 0; i < count; i++) { 115 Car* car = request->add_car(); 116 randomCar(car); 117 result += carValue(*car); 118 } 119 return result; 120 } 121 static void handleRequest(const ParkingLot& request, TotalValue* response) { 122 uint64_t result = 0; 123 for (auto& car: request.car()) { 124 result += carValue(car); 125 } 126 response->set_amount(result); 127 } 128 static inline bool checkResponse(const TotalValue& response, uint64_t expected) { 129 return response.amount() == expected; 130 } 131 }; 132 133 } // namespace protobuf 134 } // namespace benchmark 135 } // namespace capnp 136 137 int main(int argc, char* argv[]) { 138 return capnp::benchmark::benchmarkMain< 139 capnp::benchmark::protobuf::BenchmarkTypes, 140 capnp::benchmark::protobuf::CarSalesTestCase>(argc, argv); 141 }