Skip to content

Commit

Permalink
Merge pull request #11 from tvercaut/master
Browse files Browse the repository at this point in the history
Add simple github CI + tested two more libs
  • Loading branch information
gaspardpetit authored Jun 7, 2024
2 parents 2194391 + 323811e commit f2539b8
Show file tree
Hide file tree
Showing 16 changed files with 1,093 additions and 174 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CMake

on: [push, pull_request]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
with:
submodules: 'true'

- name: Configure CMake
# Configure CMake in a 'build' subdirectory.
# `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} .

- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

- name: Test
working-directory: ${{github.workspace}}/build
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C ${{env.BUILD_TYPE}} --verbose

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ base64.bin
Makefile
CTestTestfile.cmake
*.vcxproj.user

# Other
.#*
13 changes: 10 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "libs/googletest"]
path = libs/googletest
url = https://github.com/google/googletest.git
[submodule "libs/cppcodec"]
path = libs/cppcodec
url = https://github.com/tplgy/cppcodec.git
Expand Down Expand Up @@ -55,3 +52,13 @@
[submodule "libs/IMUtility"]
path = libs/IMUtility
url = https://github.com/IMProject/IMUtility.git
[submodule "libs/base64-tl"]
path = libs/base64-tl
url = [email protected]:tobiaslocker/base64.git
branch = master
[submodule "libs/base64pp"]
path = libs/base64pp
url = [email protected]:matheusgomes28/base64pp.git
[submodule "libs/base64-aklomp"]
path = libs/base64-aklomp
url = [email protected]:aklomp/base64.git
147 changes: 75 additions & 72 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,82 +1,85 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
#CLANG compiler activation options
SET (CMAKE_C_COMPILER "/usr/bin/clang-12")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++-12")
cmake_minimum_required(VERSION 3.25)
project(base64-benchmark)

SET(CMAKE_BUILD_TYPE Release)
SET(NAME base64.bin)
PROJECT(${NAME})
ENABLE_TESTING()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Update if necessary
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
IF("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2")
else()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
endif()
endif()
set(CMAKE_BUILD_TYPE Release)
enable_testing()

# BUILD AND INCLUDE GOOGLETEST
ADD_SUBDIRECTORY(libs/googletest/)
INCLUDE_DIRECTORIES(libs/googletest/googletest/include)
# Get googletest
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 750d67d809700ae8fca6d610f7b41b71aa161808
SYSTEM
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

INCLUDE_DIRECTORIES(libs)
set_target_properties(gtest PROPERTIES CXX_CLANG_TIDY "")
set_target_properties(gtest_main PROPERTIES CXX_CLANG_TIDY "")
set_target_properties(gmock PROPERTIES CXX_CLANG_TIDY "")
set_target_properties(gmock_main PROPERTIES CXX_CLANG_TIDY "")

AUX_SOURCE_DIRECTORY(./src/ CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/adp-gmbh.ch CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/apache CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/arduino CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/DaedalusAlpha CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/ElegantDice CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/gnome CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/InternetSoftwareConsortium CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/JouniMalinen CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/libb64 CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/libcurl CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/LihO CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/ManuelMartinez CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/NibbleAndAHalf CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/omnifarious CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/polfosol CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/user152949 CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/wikibooks.org CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/adition CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/A.Hristov CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/tomykaria CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/stov-180947 CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/libb64/libb64/src C_SOURCES)
AUX_SOURCE_DIRECTORY(./src/picobase64 C_SOURCES)
add_subdirectory(./libs/base64pp)
add_subdirectory(./libs/base64-aklomp)

AUX_SOURCE_DIRECTORY(./libs/chromium/modp_b64 CTR_SOURCES)
AUX_SOURCE_DIRECTORY(./src/modp_b64_chromium CTR_SOURCES)
include_directories(libs)

INCLUDE_DIRECTORIES(libs/cppcodec)
AUX_SOURCE_DIRECTORY(./src/cppcodec CTR_SOURCES)
aux_source_directory(./src/ CTR_SOURCES)
aux_source_directory(./src/adp-gmbh.ch CTR_SOURCES)
aux_source_directory(./src/apache CTR_SOURCES)
aux_source_directory(./src/arduino CTR_SOURCES)
aux_source_directory(./src/base64pp CTR_SOURCES)
aux_source_directory(./src/base64-aklomp CTR_SOURCES)
aux_source_directory(./src/base64-tl CTR_SOURCES)
aux_source_directory(./src/DaedalusAlpha CTR_SOURCES)
aux_source_directory(./src/ElegantDice CTR_SOURCES)
aux_source_directory(./src/gnome CTR_SOURCES)
aux_source_directory(./src/InternetSoftwareConsortium CTR_SOURCES)
aux_source_directory(./src/JouniMalinen CTR_SOURCES)
aux_source_directory(./src/libb64 CTR_SOURCES)
aux_source_directory(./src/libcurl CTR_SOURCES)
aux_source_directory(./src/LihO CTR_SOURCES)
aux_source_directory(./src/ManuelMartinez CTR_SOURCES)
aux_source_directory(./src/NibbleAndAHalf CTR_SOURCES)
aux_source_directory(./src/omnifarious CTR_SOURCES)
aux_source_directory(./src/polfosol CTR_SOURCES)
aux_source_directory(./src/user152949 CTR_SOURCES)
aux_source_directory(./src/wikibooks.org CTR_SOURCES)
aux_source_directory(./src/adition CTR_SOURCES)
aux_source_directory(./src/A.Hristov CTR_SOURCES)
aux_source_directory(./src/tomykaria CTR_SOURCES)
aux_source_directory(./src/stov-180947 CTR_SOURCES)
aux_source_directory(./src/libb64/libb64/src C_SOURCES)
aux_source_directory(./src/picobase64 CTR_SOURCES)

INCLUDE_DIRECTORIES(libs/boost/utility/include)
INCLUDE_DIRECTORIES(libs/boost/serialization/include)
INCLUDE_DIRECTORIES(libs/boost/config/include)
INCLUDE_DIRECTORIES(libs/boost/detail/include)
INCLUDE_DIRECTORIES(libs/boost/preprocessor/include)
INCLUDE_DIRECTORIES(libs/boost/core/include)
INCLUDE_DIRECTORIES(libs/boost/type_traits/include)
INCLUDE_DIRECTORIES(libs/boost/iterator/include)
INCLUDE_DIRECTORIES(libs/boost/mpl/include)
INCLUDE_DIRECTORIES(libs/boost/static_assert/include)
INCLUDE_DIRECTORIES(libs/boost/assert/include)
AUX_SOURCE_DIRECTORY(./src/boost CTR_SOURCES)
aux_source_directory(./libs/chromium/modp_b64 CTR_SOURCES)
aux_source_directory(./src/modp_b64_chromium CTR_SOURCES)

SET_SOURCE_FILES_PROPERTIES( ${CTR_SOURCES} PROPERTIES LANGUAGE CXX )
SET_SOURCE_FILES_PROPERTIES( ${C_SOURCES} PROPERTIES LANGUAGE C )
include_directories(libs/cppcodec)
aux_source_directory(./src/cppcodec CTR_SOURCES)

ADD_EXECUTABLE(${NAME} ${CTR_SOURCES} ${C_SOURCES})
IF(UNIX AND (NOT APPLE))
TARGET_LINK_LIBRARIES(${NAME} gtest pthread stdc++fs)
else()
TARGET_LINK_LIBRARIES(${NAME} gtest pthread)
endif()
include_directories(libs/boost/utility/include)
include_directories(libs/boost/serialization/include)
include_directories(libs/boost/config/include)
include_directories(libs/boost/detail/include)
include_directories(libs/boost/preprocessor/include)
include_directories(libs/boost/core/include)
include_directories(libs/boost/type_traits/include)
include_directories(libs/boost/iterator/include)
include_directories(libs/boost/mpl/include)
include_directories(libs/boost/static_assert/include)
include_directories(libs/boost/assert/include)
aux_source_directory(./src/boost CTR_SOURCES)

set_source_files_properties( ${CTR_SOURCES} PROPERTIES LANGUAGE CXX )
set_source_files_properties( ${C_SOURCES} PROPERTIES LANGUAGE C )

add_executable(${PROJECT_NAME} ${CTR_SOURCES} ${C_SOURCES})
target_link_libraries(${PROJECT_NAME} PRIVATE GTest::gtest GTest::gtest_main base64pp base64)

add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME})
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
# Benchmark results Results for Encoding

[The latest results are here](https://rawcdn.githack.com/gaspardpetit/base64/master/result/result.html)
[The latest results are here](https://raw.githack.com/tvercaut/base64-benchmark/master/result/result.html)

# base64

Searching the web for a C/C++ base64 implementation yields many results. The first hit as of 2016-12-10 for "c++ base64" are:

- http://www.adp-gmbh.ch/cpp/common/base64.html (René Nyffenegger's implementation which is often quoted by other implementations)
- http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c which is a stackoverflow entry with multiple "here is my implementation which I think is better"
- http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c which holds more code snippets
- http://libb64.sourceforge.net/ which is an opensource implementation claiming to be fast

Looking further, we find many more:

- http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c from Jouni Malinen under BSD license
- https://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64 has both a C and C++ implementations
Searching the web for a C/C++ base64 implementation yields many results.


How does one chose?
Expand All @@ -30,6 +20,18 @@ I do not own any of these implementations - make sure you check their respective

## Compared implementations

### base64 (Alfred Klomp)
From https://github.com/aklomp/base64
A fast C99 implementation with SIMD acceleration

### base64 (Tobias Locker)
From https://github.com/tobiaslocker/base64
A c++ single-header library implementing the approach of Nick Galbreath's in `modp_b64`

### base64 (Mat Gomes)
From https://github.com/matheusgomes28/base64pp
A c++ library written for readibility and supported by a blog post https://matgomes.com/base64-encode-decode-cpp/

### adp-gmbh (René Nyffenegger)
From http://www.adp-gmbh.ch/cpp/common/base64.html

Expand Down Expand Up @@ -92,11 +94,10 @@ From https://github.com/tplgy/cppcodec

## Conclusion

- For encoding. the Apache and the Internet Software Consortium versions, written over 15 years ago, beats most of the code snippets posted around - which brings us back to how it is important to look for existing implementations before writing new ones. The ISC implementation comes with an unconvenient license from IBM, however, granting you "immunity from suites under its patents, if any, for the use, sale or manufacture of produces to the extent that such products are used for performing Domain Name System";
- If you want the fastest implementation, go for base64 (Alfred Klomp) noting that the code base is BSD-2
- If you want a simple single-header c++ file with good performance, go for base64 (Tobias Locker)
- Some other implementations are terrible, the slower ones generally allocate memory dynamically as they convert, even though the output size is deterministic and can be preallocated;
- libb64 shows very strange performance results - I get the feeling that they are doing something neat but that I am perhaps not using their code right;
- A lot of implementations are available, everyone claims theirs is better. This test shows that unless you measure, you cannot make any claims about the performance of your code;

If you do not need support for line breaks and don't need validation of data integrity, I would recommend using Jouni Malinen or the Apache's implementation for the Encoder, and the modified Polfosol implementation for decoding.

Keep in mind that these results were all obtained using Visual Studio and could differ on another compiler.
1 change: 1 addition & 0 deletions libs/base64-aklomp
Submodule base64-aklomp added at b20a31
1 change: 1 addition & 0 deletions libs/base64-tl
Submodule base64-tl added at 387b32
1 change: 1 addition & 0 deletions libs/base64pp
Submodule base64pp added at 432c94
1 change: 0 additions & 1 deletion libs/googletest
Submodule googletest deleted from c9461a
Loading

0 comments on commit f2539b8

Please sign in to comment.