Articles & Books

C++ Performance: Common Wisdoms and Common "Wisdoms" -- Sergey Ignatchenko

Sergey is writing a book and making draft chapters available for review. Here are sBB_part095_BookChapter013b_v1-640x427.pngSome tried-and-true, well-illustrated and entertaining tips:

C++ Performance: Common Wisdoms and Common "Wisdoms"

by Sergey Ignatchenko

From the draft chapter intro:

The opposite of a fact is falsehood, but the opposite of one profound truth may very well be another profound truth. — Niels Bohr

There are quite a few common wisdoms when it comes to C++ and games. As it always the case when facing a bunch of common wisdoms, some of them have their merits, some are obsolete-beyond-belief, and some are just taken from a very different context and are not really applicable. Let’s take a look at the most popular ones...

Quick Q: Is final used for optimization in C++?

Quick A: Possibly.

Recently on SO:

Is final used for optimization in C++?

It can be.

An optimisation along these lines would relate to the "de-virtualization" of the virtual calls. This is not always immediately affected by the final of the class nor method. Albeit they offer help to determine this, the normal rules of the virtual functions and class hierarchy apply.

If the compiler can determine that at runtime a particular method will always be called (e.g. given the OP example, with an automatic object), it could apply such an optimisation anyway, irrespective of whether the method is final or not.

Optimisations fall under the as-if rule, that allow the compiler to apply any transformation so long as the observable behaviour is as-if the original code had been executed.

CppCon 2015 What's New in Visual C++ 2015 and Future Directions--Steve Carroll • Ayman Shoukry

Have you registered for CppCon 2016 in September? Don’t delay – Early Bird registration is open now.

While we wait for this year’s event, we’re featuring videos of some of the 100+ talks from CppCon 2015 for you to enjoy. Here is today’s feature:

What's New in Visual C++ 2015 and Future Directions

by Steve Carroll • Ayman Shoukry

(watch on YouTube) (watch on Channel 9)

Summary of the talk:

In this talk, we'll discuss new features, optimizations, and scenarios in Visual Studio 2015. We'll cover new backend optimizations, improved build throughput, new productivity and diagnostics features, and give a detailed update on our conformance progress, as well as talk about cool new c++1y features that we are shipping from await to modules.

Visual Studio isn't just for Microsoft platform developers. We'll also demonstrate our latest cross platform C++ development features for Android and iOS. We'll also give a sneak peak at our work on combining the Clang frontend with our existing backend to bring Clang support for Windows to Visual Studio.

Quick Q: was raw-pointer constructor of shared_ptr a mistake?

Quick A: No, its usage is well defined.

Recently on SO:

was raw-pointer constructor of shared_ptr a mistake?

In hindsight, given make_shared, would shared_ptr have a constructor that takes a raw pointer had it been introduced with C++11?
What if you don't control the allocation of the object? What if you need to use a custom deleter? What if you need list-initialization instead of parens?

None of these cases is handled by make_shared.

Additionally, if you're using weak_ptr, a shared_ptr allocated via make_shared won't free any memory until all the weak_ptrs are destroyed as well. So even if you have a normal shared pointer where none of the above apply, it's possible that you may still prefer the raw pointer constructor.

Yet another situation would be if your type provides overloads for operator new and operator delete. These may make it ill-suited for make_shared, since those overloads will not be called - and presumably they exist for a reason.

Quick Q: What makes moving objects faster than copying?

Quick A: it allows to steal ressources instead of creating new ones.

Recently on SO:

What makes moving objects faster than copying?

It's all about implementation. Consider simple string class:

class my_string {
  char* ptr;
  size_t capacity;
  size_t length;
};

Semantics of copy requires us to make a full copy of string including allocation of another array in dynamic memory and copying *ptr contents there, which is expensive.

Semantics of move requires us only to transfer the value of pointer itself to new object without duplicating contents of string.

If, of course, class doesn't use dynamic memory or system resources, then there is no difference between moving and copying in terms of performance.

Quick Q: Why assigning a value is calling the implicit constructor?

Quick A: Because the default assignement operator knows only the type of your object, which it can get be calling the constructor.

Recently on SO:

What is the point of calling constructor with implicit conversion instead of assignment operator after an object is initalized?

There is no implicit CBox::operator=(double), so box = 2.0; has to create a temporary CBox object. It's equivalent to box = CBox(2.0);.

Making your constructor explicit disallows the implicit conversion from double to CBox, so no appropriate assignment operator exists, and you get a compile error.

Quick Q: Why is there no to_string(const string&)?

Quick A: If you need such a function you can create it.

Recently on SO:

Why is there no to_string(const string&)?

You can just write your own templated function with proper overloads as follows:

#include <iostream>
#include <string>
using namespace std;

template<typename T>
std::string toString(const T& t) {
    return std::to_string(t);
}

std::string toString(const char* t) {
    return t;
}

std::string toString(const std::string& t) {
    return t;
}

int main() {
    cout << toString(10) << endl;
    cout << toString(1.5) << endl;
    cout << toString("char*") << endl;
    cout << toString(std::string("string")) << endl;
    return 0;
}

Quick Q: Being smart with smart pointers: avoiding shared_ptr overuse

Quick A: Use unique_ptr when you can.

Recently on SO:

Being smart with smart pointers: avoiding shared_ptr overuse

To allow unique_ptr/shared_ptr, you may use template:

// Dispatcher for make_unique/make_shared
template <template <typename...> class Ptr, typename T>
struct make_helper;

template <typename T>
struct make_helper<std::unique_ptr, T>
{
    template <typename ...Ts>
    std::unique_ptr<T> operator() (Ts&&... args) const {
        return std::make_unique<T>(std::forward<Ts>(args)...);
    }
};

template <typename T>
struct make_helper<std::shared_ptr, T>
{
    template <typename ...Ts>
    std::shared_ptr<T> operator() (Ts&&... args) const {
        return std::make_shared<T>(std::forward<Ts>(args)...);
    }
};

template <template <typename...> class Ptr, typename T, typename ... Ts>
auto make(Ts&&... args)
{
    return make_helper<Ptr, T>{}(std::forward<Ts>(args)...);
}

And then

bool get_resource_parameters(Param1& param1,..., ParamN& paramN)
{
    //...
}

template <template <typename...> class Ptr>
Ptr<resource> open_resource(...)
{
   Param1 param1;
   ...
   ParamN paramN;
   if(!get_resource_parameters(param1, ..., paramN))
       return nullptr;

   return = make<Ptr, resource>(param1, ..., paramN);
}

And check for nullptr instead of split bool and smart_pointer.

RAII versus Exceptions--Arne Mertz

There is no fight, is there?

RAII versus Exceptions

by Arne Mertz

From the article:

Recently I received a question on Twitter whether to prefer RAII over Exceptions. I have seen similar questions being asked again and again over time, so there seems to be some need for clarification...

An Overview of Static Analyzers for C/C++ Code--Aleksandr Alekseev

Which static tools do you use?

An Overview of Static Analyzers for C/C++ Code

by Aleksandr Alekseev

From the article:

C and C++ programmers tend to make mistakes when writing code.

Many of these mistakes can be found using -Wall, asserts, tests, meticulous code review, IDE warnings, building with different compilers for different operating systems running on different hardware configurations, and the like. But even all these means combined often fail to reveal all the bugs. Static code analysis helps improve the situation a little. In this post, we will take a look at some static analysis tools. [The author of this article is not an employee of our company, and his opinion may be different from ours.]...