1 2 Previous Next 19 Replies Latest reply: Jul 24, 2012 2:13 PM by aksarben RSS

    Coding style concerning memory efficiency

    srhcan
      Hi all,

      I have a resultset with 4 columns: start date, start time, end date and end time. The resultset will consist of 1 row or multiple rows. Now I am building a class for these 4 columns.

      First approach is to build a class with these 4 columns as non-array properties:
      public class MyClass {
         private Date startDate;
         private int startTime;
         private Date endDate;
         private int endTime;
      }
      In this case 1 row of resultset equals 1 instance of this class while multiple rows of resultset equals an array of instances of this class.


      Second approach is to build a class with these 4 columns as array properties:
      public class MyClass {
         private Date[] startDates;
         private int[] startTimes;
         private Date[] endDates;
         private int[] endTimes;
      }
      In this case 1 row of resultset equals 1 instance of this class with all its properties array length equal to 1; while multiple rows of result set equals 1 instance of this class with all its properties array length equal to no. of rows of resultset.

      Which approach is better for coding and memory efficiency? First approach looks cleaner. Will the first approach have lot more objects on heap than second approach thus making it non-efficient?
        • 1. Re: Coding style concerning memory efficiency
          DrClap
          Wrong question. You started out by designing a MyClass object (hopefully that isn't its real name) to contain some properties. Now you find you might need an array of those objects. So make an array of them already. Redesigning the class to contain arrays is just the wrong thing to do (if I understood your requirement right). So-called "memory efficiency" has nothing to do with that.
          • 2. Re: Coding style concerning memory efficiency
            srhcan
            DrClap wrote:
            Wrong question. You started out by designing a MyClass object (hopefully that isn't its real name) to contain some properties. Now you find you might need an array of those objects. So make an array of them already. Redesigning the class to contain arrays is just the wrong thing to do (if I understood your requirement right). So-called "memory efficiency" has nothing to do with that.
            I started it with first approach but I have been told that 2nd approach is better w.r.t memory efficiency. I have been told that for say 50 rows in my resultset, the first approach will have 52 objects on heap (50 objects of type MyClass + 2 objects of type Date), while the second approach will have 5 objects on heap. Is it correct?
            • 3. Re: Coding style concerning memory efficiency
              EJP
              No it isn't correct. The first approach will have one MyClass[]object, 50 MyClass objects, and 100 Date objects. The second approach will have one MyClass object, two Date[] objects 50 wide each, two int[] objects 50 wide each, and 100 Date objects. The total amount of memory consumed will be dominated by the array objects and the Date objects.
              • 4. Re: Coding style concerning memory efficiency
                DrClap
                I hope you weren't planning to make any design decisions based on these "memory efficiency" questions. Even though EJP's analysis says that the sensible design is also the most "efficient", you should still design your classes based on standard object-oriented design techniques.
                • 5. Re: Coding style concerning memory efficiency
                  gimbal2
                  DrClap wrote:
                  you should still design your classes based on standard object-oriented design techniques
                  ... and intelligence / logic thought. Lets not forget about the need to think about what you're doing.
                  • 6. Re: Coding style concerning memory efficiency
                    rp0428
                    >
                    ... and intelligence / logic thought. Lets not forget about the need to think about what you're doing.
                    >
                    Based on the content of a lot of the recent forum (many forums) posts isn't that kind of an old school concept? I didn't think they were still teaching that!
                    • 7. Re: Coding style concerning memory efficiency
                      aksarben
                      Aside from the memory issues, I'd strongly recommend you develop the habit of using objects rather than primitives for class variables such as the start & end times in your example. Using objects makes it much easier for the JVM to tell you (usually via null pointer exception) when you forgot to set a variable value. If you use primitives, on the other hand, zero might be valid value (though usually not, for a time variable), but even it if isn't, your program will probably run without crashing, making it much harder to debug.
                      • 8. Re: Coding style concerning memory efficiency
                        939520
                        The Date class can hold both date and time, so you don't need to separate them into date and time variables. So the code below may work for you. However, you may consider using Calendar class so you can manipulate date/time such as subtracting one from the other, etc easier. Alternatively, you can search google for 'java joda time' which provides a DateTime class. Unless you have millions of records, I would be far more concerned over readablity than efficiency (which may be ugly, and harder to read). Note: the main function is below is incomplete.
                        import java.util.ArrayList;
                        import java.util.Date;
                        import java.util.List;
                        
                        /** provides information on how long a given project has taken  to complete */
                        public class ProjectDuration {
                        
                             private String projectName;
                        
                             private Date startDate;
                             private Date endDate;
                        
                        
                             /** constructor */ 
                               public ProjectDuration(String projectName, Date startDate, Date endDate){
                                        this.projectName = projectName;
                        
                                  this.startDate = startDate;
                                  this.endDate = endDate;
                             }
                             public Date getStartDate(){
                                  return startDate;
                             }
                        
                                /** demo of how to use this class */
                             public static void main(String[] args){
                                  List<ProjectDuration> projectDurations = new ArrayList<ProjectDuration>();
                        
                                  for(ProjectDuration projectDuration : projectDurations){          
                                       System.out.println(projectDuration.getStartDate());
                                  }
                             }
                        }
                        • 9. Re: Coding style concerning memory efficiency
                          jschellSomeoneStoleMyAlias
                          aksarben wrote:
                          Aside from the memory issues, I'd strongly recommend you develop the habit of using objects rather than primitives for class variables such as the start & end times in your example. Using objects makes it much easier for the JVM to tell you (usually via null pointer exception) when you forgot to set a variable value. If you use primitives, on the other hand, zero might be valid value (though usually not, for a time variable), but even it if isn't, your program will probably run without crashing, making it much harder to debug.
                          Of course sufficient unit testing completely negates any of that.
                          • 10. Re: Coding style concerning memory efficiency
                            rp0428
                            >
                            Of course sufficient unit testing completely negates any of that.
                            >
                            Of course, in practice, 'sufficient unit testing' rarely exists which completely negates your complete negation.
                            • 11. Re: Coding style concerning memory efficiency
                              jschellSomeoneStoleMyAlias
                              rp0428 wrote:
                              >
                              Of course sufficient unit testing completely negates any of that.
                              >
                              Of course, in practice, 'sufficient unit testing' rarely exists which completely negates your complete negation.
                              You are suggesting that one should use objects rather than primitives so that one will get null pointer exceptions as a best practice?
                              • 12. Re: Coding style concerning memory efficiency
                                rp0428
                                >
                                You are suggesting that one should use objects rather than primitives so that one will get null pointer exceptions as a best practice?
                                >
                                Not for that specific reason although aksarben makes a valid point. I do think that an application that used objects rather than primitives would have far fewer of the kind of nasty bugs that aksarben was alluding to.

                                Sadly it seems like more and more developers these days don't really understand the limitations or the nuances of primitives.

                                As DrClap and gimbal2 have already pointed out just an initial look at the first code that was posted raises some serious questions about both of those potential data models: the Java data model as well as the database model.

                                1. Why does the DB model have a separate column for the time component?
                                2. What if the time component is NULL? How would either class instance be constructed properly?
                                3. Time in the DB is an object so why is it being converted to a primitive? What was the business reason for that?
                                4. A row in a resultset is a meaningfull representation of the query involved. So why would data model two be considered when it breaks than relationship? What is the business reason for that: and I mean business reason, not technical such as 'saving memory'.

                                A basic principle is to never throw away information unless you are absolutely sure you don't need it. And a related principle is to never expend work to convert data unless you actually need it in the converted form. Data (including numbers) in a DB are objects. The JDBC driver handles data as objects. Objects can be NULL.

                                Primitives cannot represent NULL data. So a primary consideration for converting numeric object data to primitive form is how to deal with NULL data. And then once data is in primitive form any information about possible NULL values is lost.

                                I wish there was such a thing as 'sufficient unit testing' but I've never seen it. Most of what I have seen involves people not really defining, or even knowing, WHAT needs to be tested, let alone how to actually test it.
                                • 13. Re: Coding style concerning memory efficiency
                                  939520
                                  Some additional considerations: You have a startDate, startTime, endDate, and endTime. What if they are all objects and therefore nullable? What if I provide a null startDate but non null startTime. What does that mean? I think you should specify in the javadoc that both the startDate and startTime are both required, and the endDate and endTime are both either supplied or both null (meaning the project hasn't ended). Check in the function or constructor that these conditions are provided. Also, start date/time must come before or the end date/time (can't end a project before it starts). I suggest it should be given (and documented somewhere) that all functions in your project(s) functions cannot accept null unless it's specified in the function's javadoc. As a maintainer of your project after you leave, I want to know how to properly use your function via javadoc without having to see how it's coded.

                                  Here are two links to Java Best Practices (http://www.javapractices.com) that discuss these issues. You can read up other items at that site for other ideas.

                                  http://www.javapractices.com/topic/TopicAction.do;jsessionid=A6DD6883D63A0C15A14BB83FB3837753?Id=134
                                  http://www.javapractices.com/topic/TopicAction.do?Id=5
                                  • 14. Re: Coding style concerning memory efficiency
                                    EJP
                                    As already pointed out, a Date already contains a time, so the time fields are redundant, so by taking that advice and removing them, the problem you now raise cannot arise.

                                    Curiously enough, it was you who pointed that out. Do you read your own posts?
                                    1 2 Previous Next