Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build-libs/
19 changes: 19 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ There are several implementations of HTTP server:
- C++ : [cpprestsdk](https://github.com/Microsoft/cpprestsdk)
- C++ : [restbed](https://github.com/corvusoft/restbed)
- C++ : [pistache](https://github.com/oktal/pistache)
- C++ : [poco](https://github.com/pocoproject/poco)
- PHP : Native implementation

# Benchmark
Expand Down Expand Up @@ -84,6 +85,24 @@ Benchmark was done by running `ab -n 1000 -c 1 -k <url>` (see [Apache Benchmark]

(-) Unit tests are ill-formed.

## POCO

#### Benchmark results for default JSON implementation on Linux

![poco benchmark results](https://github.com/sineang01/cpp-rest-frameworks-benchmark/blob/master/results/benchmark-poco-default_json_impl.png)

#### Benchmark results with RapidJSON on Linux

![poco benchmark results](https://github.com/sineang01/cpp-rest-frameworks-benchmark/blob/master/results/benchmark-poco-rapidjson.png)

(+) POCO has its own implementation of JSON serializer/deserializer, so you don't need to additionally include RapidJSON or other library, however the default implementation is much slower than the one using RapidJSON.

(+) Inline code documentation.

(-) No comprehensive list of implemented features.

(+) Licensed under Boost software License.

## PHP native implementation

![PHP native implementation benchmark results](https://raw.githubusercontent.com/metamaker/cpp-rest-frameworks-benchmark/master/results/benchmark-php.png)
74 changes: 54 additions & 20 deletions bootstrap.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ EOF

# Install build tools and ntp (to prevent clock skewing)

sudo mkdir /tmp/build-libs
mkdir build-libs
sudo apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages ntp cmake

# Replace nginx configuration
Expand Down Expand Up @@ -54,36 +54,51 @@ EOF
sudo apt-get install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages libcpprest-dev

# Install RapidJSON library
# RapidJSON is required for pistache and restbed samples to produce JSON result
# RapidJSON is required for pistache, restbed and POCO samples to produce JSON result

cd /tmp/build-libs
git clone https://github.com/miloyip/rapidjson
cd rapidjson
pushd build-libs

git clone https://github.com/Tencent/rapidjson.git
pushd rapidjson
git submodule update --init
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
sudo make install
popd

# Install Pistache C++ REST framework

cd /tmp/build-libs
git clone https://github.com/oktal/pistache.git
cd pistache
pushd pistache
git submodule update --init
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will ensure parallel compilation, if the systems allows it. It's a considerable speed up.

sudo make install
popd

# Install Restbed C++ REST framework

cd /tmp/build-libs
git clone --recursive https://github.com/corvusoft/restbed.git
cd restbed
pushd restbed
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
sudo make install
sudo cp -r distribution/library/* /usr/lib/
sudo cp -r distribution/include/* /usr/include/
popd

# Install POCO C++ framework

git clone https://github.com/pocoproject/poco.git
pushd poco
mkdir cmake_build
cd cmake_build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j 8
sudo make install
popd

popd

cat << EOF
|-----------------------------------|
Expand All @@ -93,18 +108,37 @@ cat << EOF
|-----------------------------------|
EOF

cd /vagrant/cpp/cpprestsdk-default_json_impl
pushd samples/cpp

pushd cpprestsdk-default_json_impl
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
popd

cd /vagrant/cpp/cpprestsdk-rapidjson
pushd cpprestsdk-rapidjson
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
popd

cd /vagrant/cpp/pistache
pushd pistache
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
popd

cd /vagrant/cpp/restbed
pushd restbed
cmake -DCMAKE_BUILD_TYPE=Release .
make
make -j 8
popd

pushd poco-default_json_impl
cmake -DCMAKE_BUILD_TYPE=Release .
make -j 8
popd

pushd poco-rapidjson
cmake -DCMAKE_BUILD_TYPE=Release .
make -j 8
popd

popd

Binary file added results/benchmark-poco-default_json_impl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added results/benchmark-poco-rapidjson.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions samples/cpp/poco-default_json_impl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.5)
project(main)

find_package(Poco REQUIRED COMPONENTS Foundation Net JSON Util)

add_executable(main main.cpp)
target_link_libraries(main
Poco::Foundation
Poco::Net
Poco::JSON
Poco::Util
)
70 changes: 70 additions & 0 deletions samples/cpp/poco-default_json_impl/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <Poco/Net/ServerSocket.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Array.h>
#include <Poco/Util/ServerApplication.h>
#include <vector>
#include <string>

class HelloRequestHandler : public Poco::Net::HTTPRequestHandler
{
public:
virtual void handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp)
{
resp.setStatus(Poco::Net::HTTPResponse::HTTP_OK);

Poco::JSON::Array JSONArray;

for (int i = 0; i < 10000; ++i)
{
Poco::JSON::Object::Ptr JSONObject = new Poco::JSON::Object(true);

std::string id("item-"); id += std::to_string(i);
JSONObject->set("id", id);
JSONObject->set("name", "Hello World");
JSONObject->set("type", "application");

JSONArray.add(Poco::Dynamic::Var(JSONObject));
}

std::ostream& out = resp.send();
JSONArray.stringify(out);
out.flush();
}
};

class HelloRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
{
public:
virtual Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest &)
{
return new HelloRequestHandler;
}
};

class HelloServerApp : public Poco::Util::ServerApplication
{
protected:
int main(const std::vector<std::string> &)
{
Poco::Net::ServerSocket socket(Poco::Net::SocketAddress(Poco::Net::AddressFamily::IPv4, 9000));
Poco::Net::HTTPServer s(new HelloRequestHandlerFactory, socket, new Poco::Net::HTTPServerParams);

s.start();
waitForTerminationRequest();
s.stop();

return Application::EXIT_OK;
}
};

int main(int argc, char** argv)
{
HelloServerApp app;
return app.run(argc, argv);
}
14 changes: 14 additions & 0 deletions samples/cpp/poco-rapidjson/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.5)
project(main)

find_package(Poco REQUIRED COMPONENTS Foundation Net JSON Util)
find_package(RapidJSON REQUIRED)

add_executable(main main.cpp)
target_include_directories(main PUBLIC ${RAPIDJSON_INCLUDE_DIRS})
target_link_libraries(main
Poco::Foundation
Poco::Net
Poco::JSON
Poco::Util
)
76 changes: 76 additions & 0 deletions samples/cpp/poco-rapidjson/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <Poco/Net/ServerSocket.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Util/ServerApplication.h>
#include <vector>
#include <string>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>

class HelloRequestHandler : public Poco::Net::HTTPRequestHandler
{
public:
virtual void handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp)
{
resp.setStatus(Poco::Net::HTTPResponse::HTTP_OK);

char _id[20];

rapidjson::StringBuffer JSONBuffer;
rapidjson::Writer<rapidjson::StringBuffer> JSONWriter(JSONBuffer);
JSONWriter.StartArray();

for (int i = 0; i < 10000; ++i)
{
JSONWriter.StartObject();

snprintf(_id, sizeof(_id), "item-%d", i);
JSONWriter.Key("id"); JSONWriter.String(_id);
JSONWriter.Key("name"); JSONWriter.String("Hello World");
JSONWriter.Key("type"); JSONWriter.String("application");

JSONWriter.EndObject();
}

JSONWriter.EndArray();

std::ostream& out = resp.send();
out << JSONBuffer.GetString();
out.flush();
}
};

class HelloRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
{
public:
virtual Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest &)
{
return new HelloRequestHandler;
}
};

class HelloServerApp : public Poco::Util::ServerApplication
{
protected:
int main(const std::vector<std::string> &)
{
Poco::Net::ServerSocket socket(Poco::Net::SocketAddress(Poco::Net::AddressFamily::IPv4, 9000));
Poco::Net::HTTPServer s(new HelloRequestHandlerFactory, socket, new Poco::Net::HTTPServerParams);

s.start();
waitForTerminationRequest();
s.stop();

return Application::EXIT_OK;
}
};

int main(int argc, char** argv)
{
HelloServerApp app;
return app.run(argc, argv);
}