Skip to content

Instantly share code, notes, and snippets.

@kheaactua
Created February 4, 2019 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kheaactua/2077a4e5cbf7364a3bd20fcd2ad22142 to your computer and use it in GitHub Desktop.
Save kheaactua/2077a4e5cbf7364a3bd20fcd2ad22142 to your computer and use it in GitHub Desktop.
Comparing using Eigen::Map vs constructing a Vector3f
project(MapPoint)
cmake_minimum_required(VERSION 3.0.2)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
add_library(StopWatch StopWatch.h StopWatch.cpp)
target_compile_features(StopWatch PUBLIC cxx_std_11)
add_executable(app main.cpp)
set_property(TARGET app PROPERTY CXX_STANDARD 11)
target_link_libraries(app StopWatch CONAN_PKG::eigen)
# vim: ts=4 sw=4 sts=0 expandtab ffs=unix,dos :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from conans import ConanFile, CMake
class MapVsConstructConan(ConanFile):
name = 'map_vs_construct'
version = '1.0'
license = 'NTC'
description = 'Comparing Eigen Map vs Construct'
settings = 'os', 'compiler', 'build_type', 'arch'
generators = 'cmake', 'virtualenv'
requires = 'eigen/[>= 3.2.5]@ntc/stable'
scm = {
'type': 'git',
'url': 'auto',
'revision': 'auto'
}
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
self.copy(pattern='bin/*')
# vim: ts=4 sw=4 expandtab ffs=unix ft=python foldmethod=marker :
#include <iostream>
#include <vector>
#include <Eigen/Core>
#include "Stopwatch/StopWatch.h"
struct point_t
{
double X;
double Y;
double Z;
int64_t timestamp;
int8_t intensity;
};
auto test_map_point(std::vector<point_t> const& points) -> double
{
double something = 0;
std::for_each(points.begin(), points.end(), [&something](point_t const& p)
{
using T = double const*;
Eigen::Stride<sizeof(double), 0> stride{};
using S = decltype(stride);
Eigen::Map<
const Eigen::Vector3d, /* Matrix type */
Eigen::Unaligned, /* MapOptions */
S /* Stride Type */
> ep(reinterpret_cast<T>(&p), 1, 3, stride);
something += ep.x();
});
return something;
}
auto test_construct_point(std::vector<point_t> const& points) -> double
{
double something = 0;
std::for_each(points.begin(), points.end(), [&something](point_t const& p)
{
Eigen::Vector3d ep(p.X, p.Y, p.Z);
something += ep.x();
});
return something;
}
auto main(int argc, char *argv[]) -> int
{
std::vector<point_t> points;
auto const n_points = 100000000;
int ms_map{0}, ms_construct{0};
double res = 0;
for (int i = 0; i<n_points; i++)
{
points.emplace_back();
points.back().X=1;
points.back().Y=2;
points.back().Z=3;
points.back().timestamp = 10;
points.back().intensity = char(15);
}
{
StopWatch s;
auto const val = test_map_point(points);
ms_map = s.ElapsedMs();
res += val;
}
{
StopWatch s;
auto const val = test_construct_point(points);
ms_construct = s.ElapsedMs();
res += val;
}
std::cout << res << "\n"; // I don't care, but I want to ensure this isn't
// optimized out by ignoring the results.
std::cout << "Operation with map: " << ms_map << " ms" << "\n";
std::cout << "Operation with construct : " << ms_construct << " ms" << "\n";
std::cout << "map/construct = " <<
((static_cast<float>(ms_map)/static_cast<float>(ms_construct))*10000.0f/100.0f)
<< "% (>100 means swap is slower)" << "\n";
std::cout << "construct/map = " <<
((static_cast<float>(ms_construct)/static_cast<float>(ms_map))*10000.0f/100.0f)
<< "% (>100 means erase is slower)" << "\n";
return 0;
}
/* vim: set ts=4 sw=4 sts=4 expandtab ffs=unix,dos : */
/*
* File: StopWatch.cpp
* Author: KjellKod
* From: https://github.com/KjellKod/StopWatch
*
* Created on 2014-02-07
*/
#include "StopWatch.h"
StopWatch::StopWatch() : mStart(clock::now()) {
static_assert(std::chrono::steady_clock::is_steady, "Serious OS/C++ library issues. Steady clock is not steady");
// FYI: This would fail static_assert(std::chrono::high_resolution_clock::is_steady(), "High Resolution Clock is NOT steady on CentOS?!");
}
StopWatch::StopWatch(const StopWatch& other): mStart(other.mStart) {
}
/// @return StopWatch::StopWatch& - assignment operator.
StopWatch& StopWatch::operator=(const StopWatch& rhs) {
mStart = rhs.mStart;
return *this;
}
/// @return the elapsed microseconds since start
uint64_t StopWatch::ElapsedUs() const {
return std::chrono::duration_cast<microseconds>(clock::now() - mStart).count();
}
/// @return the elapsed milliseconds since start
uint64_t StopWatch::ElapsedMs() const {
return std::chrono::duration_cast<milliseconds>(clock::now() - mStart).count();
}
/// @return the elapsed seconds since start
uint64_t StopWatch::ElapsedSec() const {
return std::chrono::duration_cast<seconds>(clock::now() - mStart).count();
}
/**
* Resets the start point
* @return the updated start point
*/
std::chrono::steady_clock::time_point StopWatch::Restart() {
mStart = clock::now();
return mStart;
}
/*
* File: StopWatch.h
* Author: KjellKod
* From: https://github.com/KjellKod/StopWatch
*
* Created on 2014-02-07
*/
#pragma once
#include <chrono>
class StopWatch {
public:
typedef std::chrono::steady_clock clock;
typedef std::chrono::microseconds microseconds;
typedef std::chrono::milliseconds milliseconds;
typedef std::chrono::seconds seconds;
StopWatch();
StopWatch(const StopWatch&);
StopWatch& operator=(const StopWatch& rhs);
uint64_t ElapsedUs() const;
uint64_t ElapsedMs() const;
uint64_t ElapsedSec() const;
std::chrono::steady_clock::time_point Restart();
private:
clock::time_point mStart;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment