2

I am modeling dishes that a restaurant serves. I might make a Dish class something like this:

class Dish  
  attr_accessor :name, :price, :ingredients, etc...
  def initialize(dish_name, dish_price, etc...)
    name= dish_name
    price= dish_price
  end
end

With respect to memory usage, would it be better to create instances of Dish for each dish, Dish.new("Chicken Curry", ...), or create a new class that subclasses Dish, class ChickenCurry < Dish; ...; end;? Are there any other things to consider when choosing between these two methods with respect to hardware resources?

For clarification the ChickenCurry class would only contain a constructor where it sets the appropriate fields, like so:

class ChickenCurry < Dish
  def initialize
    super("Chicken Curry", ...) 
  end
end

Which uses more resources, Dish.new or ChickenCurry.new? Is the difference negligible? I plan to have thousands of these objects so even a 10 KB difference is worth considering.

I am using JRuby so please consider the JVM when answering but answers pertaining to Matz's Ruby are welcome too.

This is NOT a question about design. I'm only interested in resource usage.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
griest
  • 410
  • 3
  • 16
  • 1
    who's going to write thousands of classes? – ergonaut Nov 12 '15 at 18:32
  • I understand the difference in programming logistics but that wasn't my question. And the classes can be created dynamically anyway. – griest Nov 12 '15 at 18:34
  • It can be done both ways. You could allow creation of dishes via composition (as in your first example), then supply an interface for that specific kind of dish if you wanted, using the values the client would have to enter to create the dish via composition. The question now is, do you actually need that extra interface/level of abstraction? Well, it doesn't seem like you are adding new attributes or behaviors, so I'd personally say it's not needed. On top of all this, you are using Java, so "*With respect to hardware resources*" - you shouldn't be worring about such low level aspects – Vince Nov 12 '15 at 18:36
  • Creating classes dynamically points to a design issue. Why don't you try it out and see what happens? – ergonaut Nov 12 '15 at 18:36
  • I know that both ways are viable. I don't need advice on how I should create my model. I am specifically interested in the memory usage. – griest Nov 12 '15 at 18:38
  • To be clear, this is not the actual context for my question, I'm just using restaurant dishes as a simple example. – griest Nov 12 '15 at 18:40
  • @VinceEmigh "you shouldn't be worring about such low level aspects" Well I am worried about it. I want my program to run on mobile devices as well as the desktop so memory is a valid concern. – griest Nov 12 '15 at 18:49
  • 2
    @griest So maybe you should be using something more native. If you're worried about memory, maybe you shouldn't use a language that requires a VM which consumes much memory, or that uses a GC which may keep dead objects in memory for extended amounts of time. My point is, if you're using Java, saving every last drop of memory should not be your main concern. I recommend switching languages. Optimizing before you even if it's needed is frowned upon (premature optimization). You might spend an hour just to save a few bytes, when profiling could easily show you where the optimizations are needed – Vince Nov 12 '15 at 18:56
  • @VinceEmigh I am well aware of Java shortcomings and the JVM's poor memory management. If you have a better suggestion of some kind of platform that will run on anything and allow me to code in Ruby then please tell me. There are reasons that I must code in Ruby that aren't relevant to this question. – griest Nov 12 '15 at 19:03
  • @griest I recommend checking out [this post](http://stackoverflow.com/questions/3103568/how-to-write-portable-code-in-c), and possibly doing a bit more independent research before jumping into this, just to make sure you understand all possible options. Also, profile your application. Don't prematurly optimize. For all you know, you could be wasting hours to save negligable amounts of memory, when other parts of your program are consuming more than you would expect. Working based on assumpsions can easily waste a lot of time – Vince Nov 12 '15 at 19:09
  • @VinceEmigh That post seems to be specific to C++. I'm avoiding all portability problems by using Java. And I'm already knee-deep in my project. The premature optimization is a good point though. – griest Nov 12 '15 at 19:21
  • Wouldn't you probably be storing the menu data in SQLite if your target is mobile? And wouldn't that fundamentally change the whole question? BTW, I don't think "I'm avoiding all portability problems by using Java" really works that way. – mu is too short Nov 12 '15 at 19:24
  • @griest You were asking if there was an alternative, so it was just a suggestion. You cannot have the best of both worlds. You cannot have the simplicity of Java with the memory efficiency of a native program. The fact that you're worring about memory in such a way suggests you should be using something native. Otherwise, you'll be spending lots of time trying to save any amount of memory you can, when in reality you could save a LOT more memory just by switching the tool you are using. Java is not a language you should be trying to squeeze every last bit of memory from. – Vince Nov 12 '15 at 19:27
  • @muistooshort Well my target isn't mobile but it would be awesome to have a mobile version of my program. By using Java I'm at least ensuring that it will be possible to have a mobile port. Maybe I shouldn't have said ALL portability problems but at least Linux and Mac users will be able to run it with relative ease. – griest Nov 12 '15 at 19:29
  • @VinceEmigh the only reason that I am worried about memory is because I am using Java. I don't want to stress the RAM any more than it already will be. And the suggestion is appreciated but I did say that I have to use Ruby: "and allow me to code in Ruby". – griest Nov 12 '15 at 19:39
  • 2
    @griest Check [this](http://stackoverflow.com/questions/239315/how-to-embed-ruby-in-c). You can use Ruby via C++. Although may I ask why you must use Ruby? Aso, you stress memory because you use Java, but you use Java for portability. Vicious cycle if you ask me. Portability seems to be at the core of it (along with Ruby support), and now you know you can achieve portability with C++. Can't force you to switch, although I'm sure it'll save you more time in the long run (not having to worry about such micro-optimizations) – Vince Nov 12 '15 at 19:51
  • 1
    But the thing is, mobile apps tend to be very different from top to bottom so trying to have a single app that works on Linux, OSX, and mobile devices generally doesn't work that well. The hardest part is usually the UI and that really needs to be platform-specific (doubly so with mobile devices), one app running everywhere tends to produce an app that doesn't feel natural anywhere. – mu is too short Nov 12 '15 at 19:51
  • @VinceEmigh That post is quite helpful thank you. As for the reason I must use ruby, the short version is because I need my program to interact in special ways with another Ruby program. And yes to me, portability is much more a priority than memory though I felt that I shouldn't completely ignore memory considerations, hence the reason for this question. – griest Nov 12 '15 at 20:12
  • @muistooshort The whole point of me writing my model in Java is so I ONLY have to code the UI for a mobile (probably Android) port. Desktop and mobile apps would be separate, though they would share the same model. I wouldn't try to make a desktop GUI run on a phone, even if it was written in Java. – griest Nov 12 '15 at 20:15
  • 1
    @griest This is sounding more like an XY problem. What special ways must you interact with another Ruby program which require you to use Ruby on both programs? It's always good to try and save memory, but doing so before you know how much memory you are actually saving is a huge time waster. It's why profiling *after* your program is completed is recommended. It may take less memory than you think, and choosing the best memory saver will have negligable difference. You can have both portability *and* memory efficiency. Keep in mind, languages are tools for different needs. – Vince Nov 12 '15 at 20:21
  • @ergonaut _who's going to write thousands of classes?_ Enterprise developers. https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition – Solomon Slow Nov 13 '15 at 00:44

2 Answers2

0

Whole purpose of inheritance is that sub classes inheriting common things from super class and adding more specific things they need.

Why a Chicken Curry should have a field file sugarQuantity when it would not have any sugar. So, IMHO you should use inheritance to make a good OO design, so have a super class which will have common things and then each subclass will inherit the common and add more specific to it.

If you will put everything in one class then it would result in code abuse with so many unnecessary field.

In short, you need to use concept of Inheritance and Cohesion for make a good OO design, as per your case.

What uses more memory, a Class object or an instance of that class?

Definitely using inheritance will result in lesser memory usage when you will construct the objects of your dishes.

An object is the runtime representation of a class and it will occupy memory as per memory requirement of fields in the class. Try to minimize the number of fields (through inheritance and actual implementation) and you will have good memory footprint. If you will put everything in one class then definitely there will be a very bad memory foot print.

Consider you have 1000 fields in same dish class, and while creating object, all 1000 fields will occupy some memory space, as per their data types.

With inheritance and cohesion, you can have far more better memory footprint + OO design.

P.S.: I am a vegetarian :)

hagrawal7777
  • 14,103
  • 5
  • 40
  • 70
0

Don't worry about memory, the main question to ask yourself is: Does your ChickenCurry has any behaviour that extends Dish's behaviour? If your answer is no (like having only the constructor as you said) then use only one class.

Make your system clear to be understood.

Keep this in your heart:

"Premature optimization is the root of all evil" - DonaldKnuth

Jonas Fagundes
  • 1,519
  • 1
  • 11
  • 18
  • Stop talking about design. This is not the actual context for my program. I used it as an example to give some clarification to my question. I am only concerned about memory usage. – griest Nov 12 '15 at 18:57
  • 1
    In terms of memory usage... it depends of the ruby implementation you are using, mainly if it caches strings (strings are mutable in ruby but they are cached the jvm in jruby for example). Your question is really low level, you will need to check how your implementation does that. If your implementation does cache the strings then having one class is more memory effective. – Jonas Fagundes Nov 12 '15 at 19:07