1

I have been coding some octave .oct files lately (C++), and for my purposes speed is of the essence.

It seems to me that creating C++ objects (in general) can take some time. I was wondering if there is some way to circumvent this? Maybe to somehow create a statically allocated object the first time the function is called and then to return it every time. Although I don't know how it could be possible to do this memory-safely.

It is safe to assume I want to return a sparse matrix object, and I know an upper bound on the number of nonzero elements, so that all the information required for creating the object once-and-for-all exists at first function call.

Just to create the object seems to take some 0.05 seconds but the overhead of calling oct file is only on magnitude 5e-5 seconds. That is a factor of a thousand which can be very impactful if the rest of the code is heavily optimized computational C-code which often runs faster than 1e-5 seconds.

11
  • 1
    Have you profiled the code and proved that it is indeed memory allocation/object construction? And not say the delay imposed by accessing data from a drive?
    – Kain0_0
    Commented Mar 10, 2020 at 23:05
  • No secondary storage is accessed, well except whatever octave may do to load and prep .oct files. Commented Mar 10, 2020 at 23:26
  • 1
    So again, have you profiled the code to identify what is slowing it down? Are you hitting a lot of page faults? Are you performing a lot of locking/unlocking? Does the thread yield on this execution path?
    – Kain0_0
    Commented Mar 11, 2020 at 1:15
  • 1
    I think this is simple a wrong statement. Creating objects in C++ is as fast as it could be, considering that you are dynamically allocating memory, and that is pretty fast. Everything else is poor coding. Don't blame the language, profile your code and find the reason it is slow.
    – Aganju
    Commented Mar 22, 2020 at 3:45
  • 1
    How is the sparse matrix internally organized in memory? Is it organized as a linked list? Linked list implies that each item requires its own allocation, which means the number of allocations will be proportional to the number of items, which will be slow.
    – rwong
    Commented Mar 25, 2020 at 14:03

2 Answers 2

2

How many objects do you have to create?

If it is just one object, then what @candied_orange said is the way to go.

If it is multiple objects, then I would suggest an object pool, which would be filled in a separate thread once it gets under a certain limit.

If it is a single threaded application and you need multiple objects, then I would also suggest an object pool, but you would allocate memory for multiple objects at once, and once it is consumed, allocate it again.

2
  • 1
    The difference in the appropriate cases for our different suggestions isn't so much "how many objects" but consumable vs persistent objects. If there is a need to toss the object aside never to use it again then your object pool is preferable. Commented Mar 11, 2020 at 8:23
  • If the object is consumable (by which I assumed you meant read only, or an object with just methods to be invoked), then yes, your approach is the best. However, even if it is persistent (object needed to be manipulated with) if there is just one such object, then your approach with the singleton or DI would work. So, I guess, both criteria need to be taken into account. Commented Mar 11, 2020 at 12:52
4

There are two patterns that cover this problem: Singleton and Pure Dependency Injection.

Singletons are widely maligned because they effectively become globals and thus have all the associated complications if you try to refactor or reuse code. But they still work as well as they ever did.

Pure Dependency Injection has you create your one shot objects in main (or the closest to it that your framework will let you get). The fancy people call that your composition root. Since main is called only once anything you build there is only built once. If you need something in different places you pass a reference (or pointer) into those different places. Done this way your one shots only get built once but can be passed anywhere. All without silly globals. Only problem is now you have to actually allow that to be wired up. It's not free. It's work. But now things are explicit about what they need. And you only take the hit for constructing these objects once at the start of the program.

If you want to pay for it later, as needed, well you could go back to the Singleton pattern. It can cache the object. But if that global thing bugs you, well you can always inject factories that also know how to cache.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.