0

How to make memory-efficient code, but still have all the possible code nicely encapsulated ?

I have a feeling that the OO (object oriented) approach is more intuitive and the code is nicely organized and encapsulated, but it can use a lot of memory, because there are usually many live object instances in the memory.

In contrast, the MVC (controller, model (database)) approach code is much less encapsulated but uses much less memory, because the objects in memory are only when some client asks for them, and then they are disposed.


I need to make an internal health monitoring system, to periodically ping ip cameras. There will be about 10,000 items (cameras) to monitor, with a boolean state - Good / Bad.

If I go the OO way - I will hold a class for each of the item, with its ping result, timer, events to notify some other items. So I will end up with 10,000 instances in memory all the time. There is not much, but what if there were 100,000,000 items. I prefer this way, because it is intuitive and I have a perfect (encapsulated) place for any code I may need to run in the concrete item class (timers, events, handlers, subscriptions).

If I go the MVC way - I will hold all the data in database, so the memory usage will be minimum. But I will have to improvise a way to trigger code execution, like periodic timers, events, handlers, subscriptions. And that code - where will it be written? Will it be nicely encapsulated? Also, what code will call those triggers? Will it also be encapsulated? For example, I can make a timers engine, and hold a dictionary of timers for each of the 10000, but then the code will not be encapsulated.

  • 1
    "a class for each of the item" what? I hope you mean object, not class. Anyway, why does each camera need its own timer? Perhaps borrowing the idea of a game loop can be helpful. By the way, yes, there are reasons to give up encapsulation. At least the conventional OO kind of encapsulation. Submitted to your consideration: Data-Oriented Design. You may also benefit from a functional core. – Theraot Jun 10 at 2:54
  • You would be better served asking more specific questions against more concrete examples. This site is intended for questions and answers, but you are attempting to use it for a more general consulting purpose which is not its intent. – Jason K. Jun 10 at 16:50
  • MVC doesn't have an opinion about encapsulation or databases. It cares that you have three modules each focused on their responsibility. Anything more is simply from a particular implementation of MVC. – candied_orange Jun 11 at 7:06
3

OO

Can be done regardless.

Even MVC is an OO design pattern, first introduced by SmallTalk a pure OO language.

Unless we are talking about a language such as JavaScript, most languages support a tightly packed data structure. So doing something OO isn't going to impact on memory efficiency very much.

A few caveats emerge when you introduce flexibility like subclassing, mixins, and property bags.

MVC

I don't think you have a tight grasp on what MVC actually is.

I think you are instead talking about Active Record sets, or similar technology where the database tables are themselves exposed as tables to your own functions.

Now it is possible to use an Active Record as the Object Model in an MVC implementation. In which case it is unfair to state that the code is less encapsulated.

  • There was an active choice to work at the level of sets of things instead of with a thing.
  • There was an active choice to use a data-agnostic and thus business logic anaemic representation.
  • There was a choice to house the business logic externally. (Otherwise the active records themselves would have been wrapped by an object).

How much memory?

  • 1 byte for a Boolean
  • 6 bytes for an IPv4 + Port (18 bytes for an IPv6 + Port)
  • 16 bytes for a GUID
  • 8 bytes for ticks at last check
  • 8 bytes for polling delay (if each camera can be polled on a different cadence)

That gives you:

  • 39 Bytes (48 Bytes Padded to 16Byte alignment) for an IPv4
  • 51 Bytes (64 Bytes Padded to 16Byte alignment) for an IPv6

1Gb of memory (1024 * 1024 * 1024 bytes)

  • 22,369,621 aligned IPv4 camera instances (27,531,841 unaligned instances)
  • 16,777,216 aligned IPv6 camera instances (21,053,761 unaligned instances)

With a few tricks, it is possible to squeeze this even further down.

Dilemma

But no matter what you do this data will exist somewhere, be it stored in the database, or in the program itself.

Note that if a program asks for more memory than can be stored in RAM, it will be paged to the disk, exactly like it would happen in a database.

A Modern computer with access to even 2GB of ram, and an SSD is more than capable of marshalling the 6GB of Memory space required for your 100,000,000 instances, because the addressable space in most 64bit applications is currently around 2^40. Well in excess of the range before you need to worry about manually swapping data out of the process to free space for further work.

If that appears to be too slow, the cheapest way to actually improve performance would be to upgrade the servers ram. 16GB is not that expensive these days, and even 64GB is reasonably priced.

If for some reason your client, who can presumably afford 100 million cameras, cannot afford either several servers each working on a subset of the problem, or enough ram to house it all in one machine, then there is not much you can do.

Database

What purpose does this database serve for you?

  • Is it just a serialisation format, to just save all the data in your program to, and then load it up again?

  • Is it an integral part of the algorithms and processes that your are implementing providing data crunching, memory management, and multiple concurrent access?

| improve this answer | |
  • The database is for persistency. But I don't want to implement in database periodic timer, or events. So I store each ip camera in database with it's ip address. But where do I put my periodic timer and logic? And where do I put the events, and the subscribers to those events? – Karandash Jun 14 at 2:23
  • I would imagine that you would persist them in the database like you do with the cameras. But just because they are persisted there does not mean you have to operate on them there. You can bulk load them into your application, or dynamically load them on demand. Your application can then performing the timing, event switching, etc... as per its business logic, and in the programming language/environment of your choice/that you've been directed to use. No need to rely on the database as anything other than a handy, queryable serialisation format. – Kain0_0 Jun 14 at 23:41
3

There is a fundamental misunderstanding when you oppose OOD and MVC.

  • MVC emerged in the area OOP and more precisely in a Smalltalk environment.
  • The separation of responsibilities between objects in the MVC pattern is in fact meant to improve the encapsulation and the clean collaboration between objects in a complex system, not to get rid of them.
  • Well designed objects do not necessarily mean memory intensive.

There is another misconception, associating MVC with a database orientd M that would short-circuit objects in memory. MVC is agnostic how the M interacts with the database. And there are many ways to design the M, for example:

  • Transaction Script and Table Module implement the model using a direct bridge to the database.
  • Domain Models implement the model using in-memory objects that use some repositories and other intermediary objects to interact with the database.
  • Active records are a variant of domain models where each memory object saves itself in the database

But there are plenty of other variants. And it's not because you'll keep a couple of domain objects in memory that you will exhaust your system (it's never the full database that is loaded, only what's needed).

If you're looking for a nice design of your M in the MVC, without loosing any of the advantages of OOD, and understanding the pros and cons of the different alternatives, I can recommend you Martin Folwers great book "Patterns of Enterprise Application Architecture". There are several chapters devoted to this subject.

| improve this answer | |
  • 1
    You're factually correct but utterly misleading. MVC as is practiced today has nothing to do with OOP. Most, if not all implementations, articles and even books start with an anemic "model" which instantly disqualifies them from being an OOP solution. There are OOP compatible MVC-type designs of course, I've never seen one out in the field though. – Robert Bräutigam Jun 10 at 9:43
  • 1
    @RobertBräutigam I deplore the misuse of MVC by some actors in the industry to mislead people about the quality of their product design. I agree with you in that the MVC acronym is widely misused: I once discovered that a popular programming book series used a .net feature to implement a table module based MVVM and fearlessly called this MVC. But I can’t agree when you say that I’m misleading. I’m not in marketing. I‘m in SWE and MVC is well described in lots of great articles and books. So I only promote the right use of that acronym ;-) – Christophe Jun 10 at 9:57
  • 1
    "Misleading" was maybe too harsh, but without a good example the term "MVC" will lead the questioner to a non-OO version for sure. That's what I mean by "mislead". So if you perhaps know/have great online articles/projects, can you share some links? Articles without complete examples don't count. – Robert Bräutigam Jun 10 at 10:37
  • @RobertBräutigam No problem, I understand. The referred book has the advantage of illustrating every topic with plenty of code, and focusing on "enterprise applications", i.e. database intensive. Indo not have online resources at hand, but if I find some I’ll make an update. – Christophe Jun 10 at 12:31
  • 'Domain Models'. I am looking for a design of a general enterprise system, using domain driven modeling. Specifically, is there a way to have the event at the entity level (oo), but if there are no subscribers - then I don't want to hold the entity in memory (like mvc). A third option is a true mvc where I bring up the entity from database for every request - but that is very slow, or to add caching. I would like to find a design of infrastructure, which will cover all those issues from the start, so I don't have to come with adhoc solutions when problems arise, because I know they will. – Karandash Jun 14 at 2:32
1

Your assumption that you have to have an object for each ip camera if you do OOP does not hold. Also, you seem to be assuming that ip camera objects needs to hold the data associated with them at all times or that every ip camera object has to be present at all times, this is also not true.

I know this is unfortunately what OO looks like in many projects, but neither assumption is actually needed for OO. In OO you model what you need exactly. If you just want to present the current values why not do:

public interface IpCameras {
   UIComponent displayState();
}

There is no reason in OO whatsoever to have anything more than that, if this is your use-case. All the "patterns", "MVC", stuff like that doesn't really matter. Do proper modelling and most if not all optimization problems will have a proper place to go to.

Update: with more requirements. Pinging and timing: I would assume scheduling code is already there on the platform, so I would perhaps do this:

public interface IpCameras {
   UIComponent displayState();

   void pingAll();
}

With pingAll() called to ping through all cameras. This could be internal too, the IpCameras could do this without exposing this method, both are fine.

To notify things, perhaps this method could be extended with a parameter:

void pingAll(PingClient client);

public interface PingClient {
   void onPinged(...ip camera...);

   void onFailed(...ip camera...);
}

You then can have multiple implementations of PingClient, separating the different things you want to do with this information. Some implementations might be: PingClients (for more then one client), RealTimeClients (for online apps), NotificationsClients (for email clients or whatever), ThreeFailsClient (to fail the delegate only when 3 consecutive fails were registered), etc.

Again, you can do all this without instantiating an object for each camera and without keeping any superfluous data in memory while completely preserving encapsulation.

| improve this answer | |
  • I don't just display someone status of camera. I need to ping each camera periodically, and if it fails 3 times I need to send email. Also there are a few app clients that would like to get an instant notification upon 3 fails. Where do I put the code of periodic timer, notifications, and subscribers to those notifications? – Karandash Jun 14 at 2:42
  • I am looking for that needed generic platform design, that has the code execution scheduling and maybe other things. – Karandash Jun 14 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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