Bitfields vs. Polymorphism for game map object attributes - c++

This optimzation question has been bugging me for the last day.
In my program (a simple roguelike game), I use bitwise flags to store the attributes of map objects, such as if they are solid, or if they are rendered. However, I could accomplish the thing using polymorphism to return the appropriate value.
My question is, is either way significantly faster or slower than the other way when used in a linked list loop? Also, is one better practice than the other?
An example of the code:
XMapObject *List = ListStart;
while(List != NULL)
{
if(List->MapObjectFlags & MAPOBJECTFLAG_RENDER)
OR
if(List->Render())
{
return List->Type;
}
else
{
List = List->Next;
}
}
bool XMapObject::Render()
{
return 1;
}
Thanks.

A bitwise operation is always faster than a virtual function call.

Related

Objects vs. Static Variables for retaining function state

I have a function which processes data that comes as a sequence. Because of this, I need to know the value of certain variables from the last function call during the current function call.
My current approach to doing this is to use static variables. My function goes something like this:
bool processData(Object message){
static int lastVar1 = -1;
int curVar1 = message.var1;
if (curVar1 > lastVar1){
// Do something
}
lastVar1 = curVar1;
}
This is just a small sample of the code; in reality I have 10+ static variables tracking different things. My gut tells me using so many static variables probably isn't a good idea, though I have nothing to back that feeling up.
My question: Is there a better way to do this?
An alternative I've been looking into is using an object whose fields are lastVar1, lastVar2, etc. However, I'm not sure if keeping an object in memory would be more efficient than using static variables.
Your question has a taste of being purely about style and opinions, though there are aspects that are not a matter of opinion: multithreading and testing.
Consider this:
bool foo(int x) {
static last_val = -1;
bool result = (x == last_val);
last_val = x;
return result;
}
You can call this function concurrently from multiple threads but it wont do the expected. Moreover you can only test the function by asserting that it does the right thing:
foo(1);
assert( foo(1) ); // silenty assumes that the last call did the right thing
To setup the preconditions for the test (first line) you already have to assume that foo(1) does the right thing, which somehow defeats the purpose of testing that call in the second line.
If the methods need the current object and the previous object, simply pass both:
bool processData(const Object& message,const Object& previous_message){
if (message.var1 > previous_message.var1){
// Do something
return true;
}
return false;
}
Of course this just shifts the issue of keeping track of the previous message to the caller, though thats straight-forward and requires not messing around with statics:
Object message, old_message;
while ( get_more( message )) {
processData(message, old_message);
old_message = message;
}

How to neatly write two functions - one for checking if a solution exists, and another one for getting all solutions?

The obvious way is to just write two functions, but then they are almost identical. What I'm doing now is a function template with the return type (either bool or vector<something>) as the argument
template<typename ReturnType>
ReturnType foo(...){
constexpr bool return_bool = std::is_same<ReturnType, bool>::value;
ResultType results; //hopefully, the compiler takes it out in the bool case
And the plan is to use if constexpr(return_bool) when needed. But then I get this reoccurring piece of code
ReturnType result = foo<ResultType>(...);
if constexpr(return_bool){
if(result) return true;
}else std::copy(result.begin(), result.end(), std::back_inserter(results));
The return statement makes it hard to use standard anti-repetition techniques. I could use macros but then perhaps the repetition is better. Getting either all solutions or just the information whether one exists seems like a fairly general problem, is there a better way to do it?
I should've added that the function is performance-critical in the "does a solution exist?" case. That's why I want to have another version there and also why I don't want any costly abstractions.
You want two opposite features :
Reusing one solution in the other to avoid replication
Having an optimized version for solutionExists() to avoid a full result search
You didn't specify what is the solution your function returns, so I will explain why you can't have both using a simple example : your function is returning the number of ocurences of 0 in a vector of integers.
The function returning all solutions would look like this :
int GetNumberOfOccurencesOf0(const vector<int>& data)
{
int occurences = 0;
for (int i : data)
{
if (i == 0)
++occurences;
}
return occurences;
}
If you are not concerned about performance, your function for returning if there is a solution can be :
bool AreThereOccurencesOf0(const vector<int>& data)
{
return (GetNumberOfOccurencesOf0(data) > 0);
}
Note that there is no code duplication but the solution is not optimal : the data vector is iterated entirely. If you want an optimized solution, it would look like this :
bool AreThereOccurencesOf0(const vector<int>& data)
{
for (int i : data)
{
if (i == 0)
return true;
}
return false;
}
If your problem requires an optimized version of solutionExists(), you should write it and it should not need to reuse code from the getAllSolutions() function.

Copy structure without pointers

I'm trying to create an interface between physical components (Arduinos) and flight simulator in order to control and display simulator events from self-built parts. I have started learning C++ in school, but have never been quite keen on it.
Yet the library I use to communicate with my flight simulator is written in C++ (it's called SimConnect) and so is the SDK of my payware airplane. Therefore I figured it's probably easier to get back into it than creating wrappers or such for another programming language.
Every time I receive new data from the simulator, I pass it into the function ProcessNGXData:
PMDG_NGX_Data* previousData;
bool alreadyProcessed = false;
void ProcessNGXData(PMDG_NGX_Data *data)
{
if (!alreadyProcessed || data->LTS_TaxiSw != previousData->LTS_TaxiSw) {
if (data->LTS_TaxiSw)
printf("Taxi Lights: [ON]\n");
else
printf("Taxi Lights: [OFF]\n");
}
if (!alreadyProcessed) {
alreadyProcessed = true;
}
previousData = data;
}
In other programming languages, this would probably work fine, hence I tried to implement it like this. However, C++ pointers are a slight bit more complicated to me.
The condition data->LTS_TaxiSw != previousData->LTS_TaxiSw never evaluates to true. From my understanding, that is because both data and previousData are pointers to exactly the same structure and thus can never be different.
With my little knowledge and not much understanding of those pointers, how would I do this? Is there a way to copy the structure, so they can differ?
Thanks in advance.
Declare previousData like this:
PMDG_NGX_Data previousData;
(without the asterisk). Now, when you want to 'save' the structure, do this:
previousData = *data;
(right hand side has an asterisk). Note that this assumes that PMDG_NGX_Data is copy-able and a fixed size. If it's an interface or an abstract class, then this won't be possible. Perhaps the API gives you a "Clone" or "Copy" method you can call.
If PMDG_NGX_Data is not too big to copy every ProcessNGXData you can try this:
PMDG_NGX_Data previousData;
bool alreadyProcessed = false;
void ProcessNGXData(PMDG_NGX_Data *data)
{
if (!alreadyProcessed || data->LTS_TaxiSw != previousData.LTS_TaxiSw) {
if (data->LTS_TaxiSw)
printf("Taxi Lights: [ON]\n");
else
printf("Taxi Lights: [OFF]\n");
}
if (!alreadyProcessed) {
alreadyProcessed = true;
}
previousData = *data;
}
If it is too big, you can create a struct that will hold only the fields you need to compare and will be initialized by PMDG_NGX_Data and initialize that struct every ProcessNGXData.

Filling list inside object and accessing to it later

I'm sorry if the title isn't very explicit, but I'll try to explain it better. I'm not very familiar with c++ and I'm using openFrameworks for the first time. I'm trying to do something that's probably quite easy, at least in other languages it is, but I'm not being able to do it :(
I have a class Video and inside it I have an object list<ofImage> keyFrames; and several methods to interact with it like the following:
void addKeyFrame(ofImage img) {
if(keyFrames.size() == 0) {
keyFrames.push_front(img);
}
else {
keyFrames.push_back(img);
}
}
list<ofImage> * getKeyFrames() {
list<ofImage> *list = &keyFrames;
return list;
}
void clearKeyFrames() {
keyFrames.clear();
}
In other class I have several Video objects and I have a function that uses addKeyFrame(ofImage img) to fill the list for each object. In the end of that function if I print the list size it is greater than zero.
Inside draw() function I iterate each Video object and I try to draw each image inside their keyFrame list, but the list is always empty and I just filled it with images... I'm using getKeyFrames() function to return a pointer to the list. How can it be empty if I just added objects to it in another function and if I verified that the size was greater than zero? And if I try to debug the application I feel even more lost lol.
Please tell me if you need anymore information and if you know what I'm doing wrong. Thanks!
Ok, A few little things:
1- You shouldn't check for empty lists (or any other STL containers) like this:
if(keyFrames.size() == 0)
This is faster and more "stylish":
if(keyFrames.empty())
2- You've created an unnecessary variable here:
list<ofImage> * getKeyFrames() {
list<ofImage> *list = &keyFrames;
return list;
}
You could do just:
list<ofImage> * getKeyFrames() {
return &keyFrames;
}
3- Pointers are not (most times) the best solution in C++. A reference is the most used substitute, but it would be even better in htis case if you returned an iterator:
list<ofImage>::iterator GetBeginIterator() {
return keyFrames.begin();
}
This way you could use the iterator just like a pointer, increasing it to iterate trough the frames and dereferencing it (with * operator)...

Lazy object creation in C++, or how to do zero-cost validation

I've stumbled across this great post about validating parameters in C#, and now I wonder how to implement something similar in C++. The main thing I like about this stuff is that is does not cost anything until the first validation fails, as the Begin() function returns null, and the other functions check for this.
Obviously, I can achieve something similar in C++ using Validate* v = 0; IsNotNull(v, ...).IsInRange(v, ...) and have each of them pass on the v pointer, plus return a proxy object for which I duplicate all functions.
Now I wonder whether there is a similar way to achieve this without temporary objects, until the first validation fails. Though I'd guess that allocating something like a std::vector on the stack should be for free (is this actually true? I'd suspect an empty vector does no allocations on the heap, right?)
Other than the fact that C++ does not have extension methods (which prevents being able to add in new validations as easily) it should be too hard.
class Validation
{
vector<string> *errors;
void AddError(const string &error)
{
if (errors == NULL) errors = new vector<string>();
errors->push_back(error);
}
public:
Validation() : errors(NULL) {}
~Validation() { delete errors; }
const Validation &operator=(const Validation &rhs)
{
if (errors == NULL && rhs.errors == NULL) return *this;
if (rhs.errors == NULL)
{
delete errors;
errors = NULL;
return *this;
}
vector<string> *temp = new vector<string>(*rhs.errors);
std::swap(temp, errors);
}
void Check()
{
if (errors)
throw exception();
}
template <typename T>
Validation &IsNotNull(T *value)
{
if (value == NULL) AddError("Cannot be null!");
return *this;
}
template <typename T, typename S>
Validation &IsLessThan(T valueToCheck, S maxValue)
{
if (valueToCheck < maxValue) AddError("Value is too big!");
return *this;
}
// etc..
};
class Validate
{
public:
static Validation Begin() { return Validation(); }
};
Use..
Validate::Begin().IsNotNull(somePointer).IsLessThan(4, 30).Check();
Can't say much to the rest of the question, but I did want to point out this:
Though I'd guess that allocating
something like a std::vector on the
stack should be for free (is this
actually true? I'd suspect an empty
vector does no allocations on the
heap, right?)
No. You still have to allocate any other variables in the vector (such as storage for length) and I believe that it's up to the implementation if they pre-allocate any room for vector elements upon construction. Either way, you are allocating SOMETHING, and while it may not be much allocation is never "free", regardless of taking place on the stack or heap.
That being said, I would imagine that the time taken to do such things will be so minimal that it will only really matter if you are doing it many many times over in quick succession.
I recommend to get a look into Boost.Exception, which provides basically the same functionality (adding arbitrary detailed exception-information to a single exception-object).
Of course you'll need to write some utility methods so you can get the interface you want. But beware: Dereferencing a null-pointer in C++ results in undefined behavior, and null-references must not even exist. So you cannot return a null-pointer in a way as your linked example uses null-references in C# extension methods.
For the zero-cost thing: A simple stack-allocation is quite cheap, and a boost::exception object does not do any heap-allocation itself, but only if you attach any error_info<> objects to it. So it is not exactly zero cost, but nearly as cheap as it can get (one vtable-ptr for the exception-object, plus sizeof(intrusive_ptr<>)).
Therefore this should be the last part where one tries to optimize further...
Re the linked article: Apparently, the overhaead of creating objects in C# is so great that function calls are free in comparison.
I'd personally propose a syntax like
Validate().ISNOTNULL(src).ISNOTNULL(dst);
Validate() contructs a temporary object which is basically just a std::list of problems. Empty lists are quite cheap (no nodes, size=0). ~Validate will throw if the list is not empty. If profiling shows even this is too expensive, then you just change the std::list to a hand-rolled list. Remember, a pointer is an object too. You're not saving an object just by sticking to the unfortunate syntax of a raw pointer. Conversely, the overhead of wrapping a raw pointer with a nice syntax is purely a compile-time price.
PS. ISNOTNULL(x) would be a #define for IsNotNull(x,#x) - similar to how assert() prints out the failed condition, without having to repeat it.