Skip to content

Commit c2a0d8c

Browse files
authored
Adding suil C++ http framework to TechEmpower benchmarks (#6826)
* Adding suil C++ http framework to TechEmpower benchmarks * Add whitespace * Use better syntax when getting query arguments * Remove LICENSE file and unused header file
1 parent f7ba4ed commit c2a0d8c

File tree

12 files changed

+422
-0
lines changed

12 files changed

+422
-0
lines changed

frameworks/C++/suil/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# suil Benchmarking Test
2+
3+
`Suil` is C++ Micro web framework which provides API's that can be used to design web applications in C++.
4+
- [See documentation](https://suilteam.com/) for more details
5+
- [Github Repo](https://github.com/dccarter/suil)
6+
7+
### Test Type Implementation Source Code
8+
9+
* [JSON](benchmark/src/main.cpp)
10+
* [PLAINTEXT](benchmark/src/main.cpp)
11+
* [DB](benchmark/src/main.cpp)
12+
* [QUERY](benchmark/src/main.cpp)
13+
* [UPDATE](benchmark/src/main.cpp)
14+
15+
## Important Libraries
16+
The tests were run with:
17+
* [Software](https://www.example1.com/)
18+
* [Example](http://www.example2.com/)
19+
20+
## Test URLs
21+
### JSON
22+
23+
http://localhost:8080/json
24+
25+
### PLAINTEXT
26+
27+
http://localhost:8080/plaintext
28+
29+
### DB
30+
31+
http://localhost:8080/db
32+
33+
### QUERY
34+
35+
http://localhost:8080/query?queries=
36+
37+
### UPDATE
38+
39+
http://localhost:8080/update?queries=
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.scc linguist-language=C++
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
2+
### C template
3+
# Prerequisites
4+
*.d
5+
6+
# Object files
7+
*.o
8+
*.ko
9+
*.obj
10+
*.elf
11+
12+
# Linker output
13+
*.ilk
14+
*.map
15+
*.exp
16+
17+
# Precompiled Headers
18+
*.gch
19+
*.pch
20+
21+
# Libraries
22+
*.lib
23+
*.a
24+
*.la
25+
*.lo
26+
27+
# Shared objects (inc. Windows DLLs)
28+
*.dll
29+
*.so
30+
*.so.*
31+
*.dylib
32+
33+
# Executables
34+
*.exe
35+
*.out
36+
*.app
37+
*.i*86
38+
*.x86_64
39+
*.hex
40+
41+
# Debug files
42+
*.dSYM/
43+
*.su
44+
*.idb
45+
*.pdb
46+
47+
# Kernel Module Compile Results
48+
*.mod*
49+
*.cmd
50+
modules.order
51+
Module.symvers
52+
Mkfile.old
53+
dkms.conf
54+
### C++ template
55+
# Prerequisites
56+
57+
# Compiled Object files
58+
*.slo
59+
60+
# Precompiled Headers
61+
62+
# Compiled Dynamic libraries
63+
64+
# Fortran module files
65+
*.mod
66+
*.smod
67+
68+
# Compiled Static libraries
69+
*.lai
70+
71+
# Build directories
72+
.build
73+
build
74+
.creator
75+
cmake-build-*
76+
77+
# IDE files
78+
.idea
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
set(EP_INSTALL_DIR ${CMAKE_BINARY_DIR}/deps)
2+
3+
include(ExternalProject)
4+
5+
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/3rdParty)
6+
set(EP_PREFIX ${CMAKE_BINARY_DIR}/3rdParty)
7+
8+
ExternalProject_Add(catch
9+
PREFIX ${EP_PREFIX}/catch
10+
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
11+
GIT_TAG "v2.13.1"
12+
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${EP_INSTALL_DIR};-DCATCH_BUILD_EXAMPLES=OFF;-DCATCH_BUILD_TESTING=OFF;-DCATCH_INSTALL_DOCS=OFF;-DCATCH_INSTALL_HELPERS=OFF")
13+
set_target_properties(catch PROPERTIES EXCLUDE_FROM_ALL True)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
project(suil-bench VERSION 0.1.0 LANGUAGES C CXX)
3+
4+
set(SUIL_BASE_PATH "" CACHE STRING "The root path when SCF is installed")
5+
if (SUIL_BASE_PATH)
6+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${SUIL_BASE_PATH}/lib/cmake)
7+
endif()
8+
9+
option(SUIL_BENCH_DEV "Build development binaries" OFF)
10+
if (SUIL_BENCH_DEV)
11+
set(SUIL_BENCH_DEV 1)
12+
else()
13+
set(SUIL_BENCH_DEV 0)
14+
endif()
15+
16+
# Provides Suil* functions
17+
include(Suil)
18+
19+
# Start a suil project
20+
SuilStartProject(suil-bench
21+
EXPORTS ON
22+
SCC_SOURCES src/app.scc)
23+
24+
# Create an application target
25+
SuilApp(suil-bench
26+
SOURCES
27+
src/main.cpp
28+
${SUIL_PROJECT_SCC_PUB}/app.scc.cpp
29+
LIBRARIES Suil::HttpServer
30+
INSTALL ON
31+
DEPENDS suil-bench-scc
32+
DEFINES SUIL_BENCH_DEV=${SUIL_BENCH_DEV})
33+
34+
# Needed for installation to work
35+
SuilEndProject()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@PACKAGE_INIT@
2+
3+
include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
4+
check_required_components(@SUIL_PROJECT_NAME@)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <suil/base/string.hpp>
2+
#include <suil/db/symbols.scc.hpp>
3+
4+
#pragma load sbg
5+
6+
namespace suil::bench {
7+
8+
struct [[gen::sbg(json)]] Object {
9+
String message{""};
10+
};
11+
12+
struct [[gen::sbg(json)]] World {
13+
[[PRIMARY_KEY]]
14+
int id{0};
15+
int randomNumber{0};
16+
};
17+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
//
2+
// Created by Mpho Mbotho on 2021-01-15.
3+
//
4+
5+
#include <suil/base/env.hpp>
6+
#include <suil/http/server/pgsqlmw.hpp>
7+
#include <suil/http/server/endpoint.hpp>
8+
#include <suil/http/server/sysattrs.hpp>
9+
10+
11+
#include "app.scc.hpp"
12+
13+
using suil::net::ServerConfig;
14+
using suil::net::TcpSocketConfig;
15+
using suil::http::server::PgSqlMiddleware;
16+
using suil::http::server::Endpoint;
17+
using suil::http::server::SystemAttrs;
18+
using suil::http::server::Request;
19+
using suil::http::server::Response;
20+
using suil::db::Orm;
21+
using suil::db::PgSqlConnection;
22+
using suil::bench::World;
23+
24+
using WorldOrm = Orm<PgSqlConnection, suil::bench::World>;
25+
26+
#define DEFAULT_POSTGRES_CONN "postgres://build:passwd@postgres:5432/dev"
27+
28+
static inline int randnum()
29+
{
30+
// from https://stackoverflow.com/questions/1640258/need-a-fast-random-generator-for-c
31+
constexpr int MAX_VALUE = 10000;
32+
static int g_seed = 0;
33+
g_seed = (214013*g_seed+2531011);
34+
return 1 + ((g_seed>>16)&0x7FFF)%MAX_VALUE;
35+
}
36+
37+
#if SUIL_BENCH_DEV==1
38+
void seedDatabase(PgSqlConnection& conn)
39+
{
40+
constexpr int MAX_RECORDS = 10000;
41+
WorldOrm orm("world", conn);
42+
if (orm.cifne(false)) {
43+
for (int i = 0; i < MAX_RECORDS; i++) {
44+
orm.insert(World{.id = i+1, .randomNumber = randnum()});
45+
}
46+
}
47+
}
48+
#endif
49+
50+
int main(int argc, char *argv[])
51+
{
52+
suil::setup(opt(verbose, 1));
53+
auto config = ServerConfig{
54+
.socketConfig = TcpSocketConfig {
55+
.bindAddr = {.name = "0.0.0.0", .port = 8080}
56+
}
57+
};
58+
59+
Endpoint<SystemAttrs, PgSqlMiddleware> ep{"/",
60+
opt(serverConfig, std::move(config)),
61+
opt(numberOfWorkers, 0) /* Will run with number of available cores */
62+
};
63+
64+
ep.middleware<PgSqlMiddleware>().setup(
65+
suil::env("POSTGRES_CONN", DEFAULT_POSTGRES_CONN),
66+
opt(ASYNC, true), // connections are async
67+
opt(TIMEOUT, 5_sec), // timeout on db transactions
68+
opt(EXPIRES, 30_sec) // connections are cached for 30 seconds
69+
);
70+
71+
#if SUIL_BENCH_DEV == 1
72+
{
73+
scoped(conn, ep.middleware<PgSqlMiddleware>().conn());
74+
seedDatabase(conn);
75+
}
76+
#endif
77+
78+
Route(ep, "/plaintext")
79+
("GET"_method)
80+
.attrs(opt(ReplyType, "text/plain"))
81+
([]() {
82+
return suil::String{"Hello, World!"};
83+
});
84+
85+
Route(ep, "/json")
86+
("GET"_method)
87+
.attrs(opt(ReplyType, "application/json"))
88+
([]() {
89+
return suil::bench::Object{.message = "Hello, World!"};
90+
});
91+
92+
Route(ep, "/db")
93+
("GET"_method)
94+
.attrs(opt(ReplyType, "application/json"))
95+
([&ep]() {
96+
scoped(conn, ep.middleware<PgSqlMiddleware>().conn());
97+
WorldOrm orm("World", conn);
98+
suil::bench::World obj{};
99+
orm.find(opt(id, randnum()), obj);
100+
return obj;
101+
});
102+
103+
Route(ep, "/query")
104+
("GET"_method)
105+
.attrs(opt(ReplyType, "application/json"))
106+
([&ep](const Request& req, Response& resp) {
107+
auto queries = req.query().get<int>("queries") or int(1);
108+
int count = std::max(1, std::min(*queries, 500));
109+
110+
scoped(conn, ep.context<PgSqlMiddleware>(req).conn());
111+
std::vector<World> objects(count);
112+
WorldOrm orm("World", conn);
113+
for (auto& obj: objects) {
114+
orm.find(opt(id, randnum()), obj);
115+
}
116+
117+
resp.append(objects);
118+
resp.end();
119+
});
120+
121+
Route(ep, "/update")
122+
("GET"_method)
123+
.attrs(opt(ReplyType, "application/json"))
124+
([&ep](const Request& req, Response& resp) {
125+
auto queries = req.query().get<int>("queries") or int(1);
126+
int count = std::max(1, std::min(*queries, 500));
127+
128+
scoped(conn, ep.context<PgSqlMiddleware>(req).conn());
129+
std::vector<World> objects(count);
130+
131+
WorldOrm orm("World", conn);
132+
133+
for (auto& obj: objects) {
134+
orm.find(opt(id, randnum()), obj);
135+
obj.randomNumber = randnum();
136+
}
137+
138+
{
139+
suil::db::PgSqlTransaction txn(conn.get());
140+
txn.begin();
141+
142+
// Sorting transactions to avoid postgres deadlock
143+
std::sort(objects.begin(), objects.end(),
144+
[](const World& a, const World& b) { return a.id < b.id; });
145+
for (auto& obj: objects) {
146+
orm.update(obj);
147+
}
148+
}
149+
150+
resp.append(objects);
151+
resp.end();
152+
});
153+
154+
return ep.start();
155+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"framework": "suil",
3+
"tests": [
4+
{
5+
"default": {
6+
"json_url": "/json",
7+
"plaintext_url": "/plaintext",
8+
"db_url": "/db",
9+
"query_url": "/query?queries=",
10+
"update_url": "/update?queries=",
11+
"port": 8080,
12+
"approach": "Stripped",
13+
"classification": "Micro",
14+
"database": "postgres",
15+
"framework": "suil",
16+
"language": "C++",
17+
"flavor": "None",
18+
"orm": "Micro",
19+
"platform": "None",
20+
"webserver": "None",
21+
"os": "Linux",
22+
"database_os": "Linux",
23+
"display_name": "suil",
24+
"notes": "",
25+
"versus": "None"
26+
}
27+
}
28+
]
29+
}

frameworks/C++/suil/scripts/build.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Build project
6+
mkdir -p .build
7+
cd .build
8+
cmake .. -DCMAKE_BUILD_TYPE=Release \
9+
-DCMAKE_INSTALL_PREFIX=/install \
10+
-DSUIL_BASE_PATH=$(cat /var/SUIL_BASE)
11+
make install

0 commit comments

Comments
 (0)