0

I am making a cpp application. I have created a .h file with lots of static variables like

namespace MSG {
   static const int MSG_TYPE = 1;
   // many more here like strings, ints, chars.
}

This is slowing down the launch time.

I have used these variables in a lot of places.

What can i do to improve the speed while reducing the amount of effort made in changing the code ?

Improving performance is a priority, though.

Ashish Negi
  • 5,193
  • 8
  • 51
  • 95
  • use singleton pattern..that should solve the problem. – Saran-san Jun 24 '14 at 08:32
  • i hope there would we other solutions too :) – Ashish Negi Jun 24 '14 at 08:33
  • 10
    Are you sure that those variables slow down startup? How did you check it? – Wojtek Surowka Jun 24 '14 at 08:38
  • if the variable is int it can't be the main reason in slowing the application, but if it is a class that has a constructor with a high overload [connecting database or opening disk files...] this may cause slowness, but basic types like int will never slow the start up, in my opinion. – ahmedsafan86 Jun 24 '14 at 08:43
  • Make the variables non-static, move the *definitions* to a cpp file, and have `extern` *declarations* in the header. – molbdnilo Jun 24 '14 at 08:44
  • @WojtekSurowka we have a another team and they use some profiler. I think that it must be the reason. – Ashish Negi Jun 24 '14 at 08:46
  • @molbdnilo Would the variables not get initialized before the main function get executed, if i move them to cpp ? – Ashish Negi Jun 24 '14 at 08:48
  • @AshishNegi Well *if* it does slow your app (and that an if you should verify, how do you know they aren't just lazy? :) see it for yourself ). If those variables are error codes, messages etc you could use `#define` statements (yes not very `c++`ish) but it will solve your problem – Scis Jun 24 '14 at 08:49
  • @AshishNegi All "top-level" statics are initialized before `main` is entered. – molbdnilo Jun 24 '14 at 08:50
  • @molbdnilo More correctly, all variables at namespace scope will be initialized before `main` is entered, or if they are in a DLL, when the DLL is loaded. – James Kanze Jun 24 '14 at 09:44
  • how many of them do you have to slow it down? 5 billion? – PlasmaHH Jun 24 '14 at 09:48
  • @JamesKanze so how would moving variables to cpp would better launch time ? – Ashish Negi Jun 24 '14 at 09:59
  • @AshishNegi There would only be one instance of them in the entire program, and not one instance per translation unit. – James Kanze Jun 24 '14 at 10:03
  • @JamesKanze ok i read a little about translation unit and if it is compile time thing how can it effect launch-time ? should i read more ? – Ashish Negi Jun 24 '14 at 10:12
  • @AshishNegi Launch time is affected by the number of variables which need initialization. Having an instance of the variable in every translation unit means more variables than having just one instance for the entire program. – James Kanze Jun 24 '14 at 10:34
  • @JamesKanze do you mean that there are multiple `MSG::MSG_TYPE` at the run time ? – Ashish Negi Jun 24 '14 at 12:36
  • @AshishNegi There's one per translation unit. – James Kanze Jun 24 '14 at 13:08

1 Answers1

2

The fundamental problem (assuming that this really is what is slowing you down, which would rather surprise me) is that you have an instance of the variable in each translation unit that includes the header. For int, this probably isn't an issue, but if any of the types have constructors, it definitely could be. In general, except for integral constants, you probably should not have static in a header. (And be aware that if the object itself is const, it is static by default.) Thus, for a string, it should be:

namespace Msg
{
    extern std::string const someMessage;
};

and then in a source file:

std::string const Msg::someMessage( "whatever" );

(The source file should, of course, include the header.)

Note that even with integral constants, you have to be careful; if the use doesn't result in an immediate lvalue to rvalue conversion, you will need an actual data declaration. In every file that uses it in this way, since there is one instance per file.

A perhaps better solution here would be to use a class, rather than a namespace:

class Msg
{
public:
    static int const msgType = 1;
    static std::string const someMessage;
    //  ...
};

This ensures that there is only one actual instance, but still allows integral constants to work as integral constant expressions. (Here too, you need a single definition in a source file somewhere.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • i have `#ifndef` in my file. would that not prevent many instances of the variable – Ashish Negi Jun 24 '14 at 09:55
  • @AshishNegi If you're talking about an `#ifndef` as an include guard, no. It will only prevent multiple inclusions of the contents in a single translation unit. – James Kanze Jun 24 '14 at 10:02
  • but would not the final executable have only single variable ?? or am i wrong ? – Ashish Negi Jun 24 '14 at 10:13
  • @AshishNegi Include guards don't have any effect across translation units. When you declare something static, you are saying that there is a separate instance for each translation unit. – James Kanze Jun 24 '14 at 10:36
  • I made a simple program from http://stackoverflow.com/questions/17848189/const-static-variable-defined-in-header-file-has-same-address-in-different-trans with header-guards and now i understand.. thanks. – Ashish Negi Jun 24 '14 at 12:55