Skip to content

david-alvarez-rosa/CppPlayground

Repository files navigation

C++ Playground

A sandbox environment for C++ experimentation:

  • Run code with main.cpp
  • Test code with test.cpp using GoogleTest
  • Benchmark code with benchmark.cpp using GoogleBenchmark
  • View assembly with assembly.cpp

Run

Edit main.cpp file

$ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=<Debug|Release>  # Configure
$ cmake --build build  # Build
$ ./build/main  # Run
$ lldb ./build/main  # Debug

Test

Install GoogleTest

$ sudo pacman -S gtest  # Arch Linux
$ sudo apt-get install libgmock-dev libgtest-dev  # Debian-based
$ brew install googletest  # MacOS

Edit test.cpp file

$ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=<Debug|Release>  # Configure
$ cmake --build build  # Build
$ ./build/test  # Run
$ lldb ./build/test  # Debug

For running a specific tests, the following commands are useful

$ ./build/test --gtest_list_tests
$ ./build/test --gtest_filter='*.<matcher>'

Example solution for Leetcode 1 problem twoSum

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <unordered_map>
#include <vector>

class Solution {
 public:
  [[nodiscard]]
  static auto twoSum(const std::vector<int>& nums, int target) noexcept
      -> std::vector<int> {
    auto mp = std::unordered_map<int, int>{};  // (nums[i], i)
    for (auto i = 0ZU, n = nums.size(); i < n; ++i) {
      auto complement = target - nums[i];
      if (mp.contains(complement)) {
        return {static_cast<int>(i), mp[complement]};
      }
      mp[nums[i]] = static_cast<int>(i);
    }
    return {0, 0};
  }
};

TEST(SolutionTest, Test1) {
  std::vector<int> nums{2, 7, 11, 15};
  EXPECT_THAT(Solution::twoSum(nums, 9), testing::UnorderedElementsAre(0, 1));
}

TEST(SolutionTest, Test2) {
  std::vector<int> nums{3, 2, 4};
  EXPECT_THAT(Solution::twoSum(nums, 6), testing::UnorderedElementsAre(1, 2));
}

TEST(SolutionTest, Test3) {
  std::vector<int> nums{3, 3};
  EXPECT_THAT(Solution::twoSum(nums, 6), testing::UnorderedElementsAre(0, 1));
}

Benchmark

Install GoogleBenchmark C++ benchmarking framework on your machine:

$ sudo pacman -S benchmark  # Arch Linux
$ sudo apt-get install libbenchmark-dev   # Debian-based
$ brew install google-benchmark  # MacOS

Edit benchmark.cpp file

$ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release  # Configure
$ cmake --build build  # Build
$ ./build/benchmark  # Run
$ lldb ./build/benchmark  # Debug

Example from https://quick-bench.com/

#include <benchmark/benchmark.h>

static void StringCreation(benchmark::State& state) {
  for (auto _ : state) {
    auto foo = std::string{"hello"};
    benchmark::DoNotOptimize(foo);
  }
}
BENCHMARK(StringCreation);

static void StringCopy(benchmark::State& state) {
  auto foo = std::string{"hello"};
  for (auto _ : state) {
    auto bar = std::string{foo};
    benchmark::DoNotOptimize(bar);
  }
}
BENCHMARK(StringCopy);

That generates the following output

Running build/benchmark
Run on (14 X 4400 MHz CPU s)
CPU Caches:
  L1 Data 48 KiB (x7)
  L1 Instruction 64 KiB (x7)
  L2 Unified 2048 KiB (x7)
  L3 Unified 12288 KiB (x1)
Load Average: 0.45, 0.42, 0.63

---------------------------------------------------------
Benchmark               Time             CPU   Iterations
---------------------------------------------------------
StringCreation      0.922 ns        0.921 ns    765882382
StringCopy           1.35 ns         1.35 ns    520319518

Assembly

Edit assembly.cpp file

$ cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release  # Configure
$ cmake --build build  # Build
$ ./build/assembly  # Run
$ lldb ./build/assembly  # Debug

Example

auto add(int a, int b) -> int {
  return a + b;
}

auto main() -> int {
  auto result  = add(3, 5);
}

Generates build/assembly_demangled.s

add(int, int):                               # @add(int, int)
# %bb.0:
	push	rbp
	mov	rbp, rsp
	mov	dword ptr [rbp - 4], edi
	mov	dword ptr [rbp - 8], esi
	mov	eax, dword ptr [rbp - 4]
	add	eax, dword ptr [rbp - 8]
	pop	rbp
	ret

main:                                   # @main
# %bb.0:
	push	rbp
	mov	rbp, rsp
	sub	rsp, 16
	mov	edi, 3
	mov	esi, 5
	call	add(int, int)
	mov	dword ptr [rbp - 4], eax
	xor	eax, eax
	add	rsp, 16
	pop	rbp
	ret

Contributions

Suggestions or improvements? Raise a pull request!

About

A sandbox environment for C++ experimentation

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages