diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ec7d66dc..1f9ef5ed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,7 +47,7 @@ jobs: - uses: actions/checkout@v3 - name: Install dependencies run: | - sudo apt install ninja-build + sudo apt install ninja-build libbenchmark-dev if [ "${{ matrix.cxxlib }}" = "libc++" ]; then sudo apt remove -y 'libc++*' apt search libunwind @@ -71,7 +71,7 @@ jobs: export EMBEDDED_BLOCKS_RUNTIME=ON fi ls -lahR /usr/lib/llvm-${{ matrix.llvm-version }}/lib/ - cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja -DTESTS=ON -DEMBEDDED_BLOCKS_RUNTIME=$EMBEDDED_BLOCKS_RUNTIME -DCMAKE_C_COMPILER=clang-${{matrix.llvm-version}} -DCMAKE_OBJC_COMPILER=clang-${{matrix.llvm-version}} -DCMAKE_ASM_COMPILER=clang-${{matrix.llvm-version}} -DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm-version}} -DCMAKE_OBJCXX_COMPILER=clang++-${{matrix.llvm-version}} -DCMAKE_CXX_FLAGS="-stdlib=${{matrix.cxxlib}}" + cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja -DTESTS=ON -DBENCHMARKS=ON -DEMBEDDED_BLOCKS_RUNTIME=$EMBEDDED_BLOCKS_RUNTIME -DCMAKE_C_COMPILER=clang-${{matrix.llvm-version}} -DCMAKE_OBJC_COMPILER=clang-${{matrix.llvm-version}} -DCMAKE_ASM_COMPILER=clang-${{matrix.llvm-version}} -DCMAKE_CXX_COMPILER=clang++-${{matrix.llvm-version}} -DCMAKE_OBJCXX_COMPILER=clang++-${{matrix.llvm-version}} -DCMAKE_CXX_FLAGS="-stdlib=${{matrix.cxxlib}}" # Build with a nice ninja status line - name: Build working-directory: ${{github.workspace}}/build @@ -81,6 +81,10 @@ jobs: working-directory: ${{github.workspace}}/build run: | ctest --output-on-failure -j 4 + - name: Benchmark + working-directory: ${{github.workspace}}/build + run: | + ./benchmark/benchmark_objc_msgSend qemu-crossbuild: strategy: @@ -237,12 +241,12 @@ jobs: with: msystem: ${{ matrix.msystem }} update: true - install: git mingw-w64-${{ matrix.package-prefix }}-clang mingw-w64-${{ matrix.package-prefix }}-lld mingw-w64-${{ matrix.package-prefix }}-cmake + install: git mingw-w64-${{ matrix.package-prefix }}-clang mingw-w64-${{ matrix.package-prefix }}-lld mingw-w64-${{ matrix.package-prefix }}-cmake mingw-w64-${{ matrix.package-prefix }}-benchmark - name: Configure CMake run: | mkdir build cd build - ${{ matrix.cmake-flags }} cmake .. -DTESTS=ON -DCMAKE_C_COMPILER="clang" -DCMAKE_CXX_COMPILER="clang++" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DSTRICT_APPLE_COMPATIBILITY=${{ matrix.strict-apple-compatibility }} + ${{ matrix.cmake-flags }} cmake .. -DTESTS=ON -DBENCHMARKS=ON -DCMAKE_C_COMPILER="clang" -DCMAKE_CXX_COMPILER="clang++" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DSTRICT_APPLE_COMPATIBILITY=${{ matrix.strict-apple-compatibility }} - name: Build working-directory: build run: | @@ -251,6 +255,10 @@ jobs: working-directory: build run: | ctest -j 4 --output-on-failure -T test ${{ matrix.ctest-flags }} + - name: Benchmark + working-directory: build + run: | + ./benchmarks/benchmark_objc_msgSend.exe - name: Install working-directory: build run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index a9aa16b5..5a770e2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,7 @@ option(DEBUG_ARC_COMPAT "Log warnings for classes that don't hit ARC fast paths" OFF) option(ENABLE_OBJCXX "Enable support for Objective-C++" ON) option(TESTS "Enable building the tests") +option(BENCHMARKS "Enable building the benchmarks" OFF) option(EMBEDDED_BLOCKS_RUNTIME "Include an embedded blocks runtime, rather than relying on libBlocksRuntime to supply it" ON) option(STRICT_APPLE_COMPATIBILITY "Use strict Apple compatibility, always defining BOOL as signed char" OFF) @@ -448,6 +449,10 @@ if (TESTS) add_subdirectory(Test) endif (TESTS) +if (BENCHMARKS) + add_subdirectory(benchmarks) +endif() + CHECK_CXX_SOURCE_COMPILES(" #include extern \"C\" { diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt new file mode 100644 index 00000000..f77a90c4 --- /dev/null +++ b/benchmarks/CMakeLists.txt @@ -0,0 +1,6 @@ +find_package(benchmark REQUIRED) + +add_executable(benchmark_objc_msgSend objc_msgSend.cpp TestClass.m) + +target_compile_options(benchmark_objc_msgSend PRIVATE "-fobjc-runtime=gnustep-2.0") +target_link_libraries(benchmark_objc_msgSend benchmark::benchmark objc) diff --git a/benchmarks/TestClass.m b/benchmarks/TestClass.m new file mode 100644 index 00000000..d3d85a28 --- /dev/null +++ b/benchmarks/TestClass.m @@ -0,0 +1,10 @@ +@interface TestClass +- (int)answer; +@end + +@implementation TestClass +- (int)answer +{ + return 42; +} +@end diff --git a/benchmarks/objc_msgSend.cpp b/benchmarks/objc_msgSend.cpp new file mode 100644 index 00000000..5f073168 --- /dev/null +++ b/benchmarks/objc_msgSend.cpp @@ -0,0 +1,23 @@ +#include +#include "../objc/runtime.h" +#include + +static id testClass; +static SEL answerSel; + +static void objc_msgSendSetup(const benchmark::State& state) { + testClass = objc_getClass("TestClass"); + answerSel = sel_registerName("answer"); +} + +static void objc_msgSend(benchmark::State& state) { + for (auto _ : state) + { + id a = objc_msgSend(testClass, answerSel); + assert((uintptr_t)a == 42); + } + } + // Register the function as a benchmark + BENCHMARK(objc_msgSend)->Setup(objc_msgSendSetup)->Repetitions(25); + + BENCHMARK_MAIN();