capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

null-carsales.c++ (5863B)


      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 Color: uint8_t {
     29   BLACK,
     30   WHITE,
     31   RED,
     32   GREEN,
     33   BLUE,
     34   CYAN,
     35   MAGENTA,
     36   YELLOW,
     37   SILVER
     38 };
     39 constexpr uint COLOR_RANGE = static_cast<uint>(Color::SILVER) + 1;
     40 
     41 struct Wheel {
     42   float airPressure;
     43   uint16_t diameter;
     44   bool snowTires;
     45 };
     46 
     47 struct Engine {
     48   uint32_t cc;
     49   uint16_t horsepower;
     50   uint8_t cylinders;
     51   uint8_t bits;
     52   inline bool usesGas()      const { return bits & 1; }
     53   inline bool usesElectric() const { return bits & 2; }
     54 
     55   inline void setBits(bool usesGas, bool usesElectric) {
     56     bits = (uint8_t)usesGas | ((uint8_t)usesElectric << 1);
     57   }
     58 };
     59 
     60 struct Car {
     61   // SORT FIELDS BY SIZE since we need "theoretical best" memory usage
     62   Engine engine;
     63   List<Wheel> wheels;
     64   const char* make;
     65   const char* model;
     66   float fuelCapacity;
     67   float fuelLevel;
     68   uint32_t weight;
     69   uint16_t length;
     70   uint16_t width;
     71   uint16_t height;
     72   Color color;
     73   uint8_t seats;
     74   uint8_t doors;
     75   uint8_t cupHolders;
     76 
     77   uint8_t bits;
     78 
     79   inline bool hasPowerWindows()  const { return bits & 1; }
     80   inline bool hasPowerSteering() const { return bits & 2; }
     81   inline bool hasCruiseControl() const { return bits & 4; }
     82   inline bool hasNavSystem()     const { return bits & 8; }
     83 
     84   inline void setBits(bool hasPowerWindows, bool hasPowerSteering,
     85                       bool hasCruiseControl, bool hasNavSystem) {
     86     bits = (uint8_t)hasPowerWindows
     87          | ((uint8_t)hasPowerSteering << 1)
     88          | ((uint8_t)hasCruiseControl << 2)
     89          | ((uint8_t)hasNavSystem << 3);
     90   }
     91 };
     92 
     93 
     94 uint64_t carValue(const Car& car) {
     95   // Do not think too hard about realism.
     96 
     97   uint64_t result = 0;
     98 
     99   result += car.seats * 200;
    100   result += car.doors * 350;
    101   for (auto wheel: car.wheels) {
    102     result += wheel.diameter * wheel.diameter;
    103     result += wheel.snowTires ? 100 : 0;
    104   }
    105 
    106   result += car.length * car.width * car.height / 50;
    107 
    108   auto engine = car.engine;
    109   result += engine.horsepower * 40;
    110   if (engine.usesElectric()) {
    111     if (engine.usesGas()) {
    112       // hybrid
    113       result += 5000;
    114     } else {
    115       result += 3000;
    116     }
    117   }
    118 
    119   result += car.hasPowerWindows() ? 100 : 0;
    120   result += car.hasPowerSteering() ? 200 : 0;
    121   result += car.hasCruiseControl() ? 400 : 0;
    122   result += car.hasNavSystem() ? 2000 : 0;
    123 
    124   result += car.cupHolders * 25;
    125 
    126   return result;
    127 }
    128 
    129 void randomCar(Car* car) {
    130   // Do not think too hard about realism.
    131 
    132   static const char* const MAKES[] = { "Toyota", "GM", "Ford", "Honda", "Tesla" };
    133   static const char* const MODELS[] = { "Camry", "Prius", "Volt", "Accord", "Leaf", "Model S" };
    134 
    135   car->make = copyString(MAKES[fastRand(sizeof(MAKES) / sizeof(MAKES[0]))]);
    136   car->model = copyString(MODELS[fastRand(sizeof(MODELS) / sizeof(MODELS[0]))]);
    137 
    138   car->color = (Color)fastRand(COLOR_RANGE);
    139   car->seats = 2 + fastRand(6);
    140   car->doors = 2 + fastRand(3);
    141 
    142   for (auto& wheel: car->wheels.init(4)) {
    143     wheel.diameter = 25 + fastRand(15);
    144     wheel.airPressure = 30 + fastRandDouble(20);
    145     wheel.snowTires = fastRand(16) == 0;
    146   }
    147 
    148   car->length = 170 + fastRand(150);
    149   car->width = 48 + fastRand(36);
    150   car->height = 54 + fastRand(48);
    151   car->weight = car->length * car->width * car->height / 200;
    152 
    153   car->engine.horsepower = 100 * fastRand(400);
    154   car->engine.cylinders = 4 + 2 * fastRand(3);
    155   car->engine.cc = 800 + fastRand(10000);
    156   car->engine.setBits(true, fastRand(2));
    157 
    158   car->fuelCapacity = 10.0 + fastRandDouble(30.0);
    159   car->fuelLevel = fastRandDouble(car->fuelCapacity);
    160   bool hasPowerWindows = fastRand(2);
    161   bool hasPowerSteering = fastRand(2);
    162   bool hasCruiseControl = fastRand(2);
    163   car->cupHolders = fastRand(12);
    164   bool hasNavSystem = fastRand(2);
    165   car->setBits(hasPowerWindows, hasPowerSteering, hasCruiseControl, hasNavSystem);
    166 }
    167 
    168 class CarSalesTestCase {
    169 public:
    170   typedef List<Car> Request;
    171   typedef uint64_t Response;
    172   typedef uint64_t Expectation;
    173 
    174   static uint64_t setupRequest(List<Car>* request) {
    175     uint64_t result = 0;
    176     for (auto& car: request->init(fastRand(200))) {
    177       randomCar(&car);
    178       result += carValue(car);
    179     }
    180     return result;
    181   }
    182   static void handleRequest(const List<Car>& request, uint64_t* response) {
    183     *response = 0;
    184     for (auto& car: request) {
    185       *response += carValue(car);
    186     }
    187   }
    188   static inline bool checkResponse(uint64_t response, uint64_t expected) {
    189     return response == expected;
    190   }
    191 };
    192 
    193 }  // namespace null
    194 }  // namespace benchmark
    195 }  // namespace capnp
    196 
    197 int main(int argc, char* argv[]) {
    198   return capnp::benchmark::benchmarkMain<
    199       capnp::benchmark::null::BenchmarkTypes,
    200       capnp::benchmark::null::CarSalesTestCase>(argc, argv);
    201 }