Commons DbUtils
  1. Commons DbUtils
  2. DBUTILS-37

BeanListHandler#handle(ResultSet) is not optimal

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.2
    • Labels:
      None

      Description

      I use the BeanListHandler for huge ResultSets (about 1000000 rows), and I searched through the code to see if I could gain little time.

      It appeared to me that the following code - in BeanProcessor.class - was executed too many times:

              PropertyDescriptor[] props = this.propertyDescriptors(type);
              ResultSetMetaData rsmd = rs.getMetaData();
              int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
      

      for the following reason.
      Since BeanListHandler extends GenericListHandler, the method #handle(ResultSet) calls #handleRow(ResultSet) for each row in the ResultSet,
      which in the case of a BeanListHandler, calls RowProcessor#toBean(ResultSet, Class),
      which itself calls BeanProcessor#toBean(ResultSet, Class).

      A very simple way to make the BeanListHandler#handle(ResultSet) method faster is to override the GenericListHandler#handle(ResultSet) method by this code:

          public Object handle(ResultSet rs) throws SQLException {
              return this.convert.toBeanList(rs, type);
          }
      

      This way, the code I showed would be called only once, as it would not call BeanProcessor#toBean(ResultSet, Class) for each row but BeanProcessor#toBeanList(ResultSet, Class).

      1. OptimalBeanListHandler.patch
        2 kB
        Julien Aymé
      2. OptimalBeanListHandler.java
        3 kB
        Julien Aymé

        Activity

        Julien Aymé created issue -
        Julien Aymé made changes -
        Field Original Value New Value
        Attachment OptimalBeanListHandler.patch [ 12356968 ]
        Attachment OptimalBeanListHandler.java [ 12356969 ]
        Dennis Lundberg made changes -
        Description I use the BeanListHandler for huge ResultSets (about 1000000 rows), and I searched through the code to see if I could gain little time.

        It appeared to me that the following code - in BeanProcessor.class - was executed too many times:

                PropertyDescriptor[] props = this.propertyDescriptors(type);
                ResultSetMetaData rsmd = rs.getMetaData();
                int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);

        for the following reason.
        Since BeanListHandler extends GenericListHandler, the method #handle(ResultSet) calls #handleRow(ResultSet) for each row in the ResultSet,
        which in the case of a BeanListHandler, calls RowProcessor#toBean(ResultSet, Class),
        which itself calls BeanProcessor#toBean(ResultSet, Class).

        A very simple way to make the BeanListHandler#handle(ResultSet) method faster is to override the GenericListHandler#handle(ResultSet) method by this code:
            public Object handle(ResultSet rs) throws SQLException {
                return this.convert.toBeanList(rs, type);
            }
        This way, the code I showed would be called only once, as it would not call BeanProcessor#toBean(ResultSet, Class) for each row but BeanProcessor#toBeanList(ResultSet, Class).
        I use the BeanListHandler for huge ResultSets (about 1000000 rows), and I searched through the code to see if I could gain little time.

        It appeared to me that the following code - in BeanProcessor.class - was executed too many times:

        {code}
                PropertyDescriptor[] props = this.propertyDescriptors(type);
                ResultSetMetaData rsmd = rs.getMetaData();
                int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
        {code}

        for the following reason.
        Since BeanListHandler extends GenericListHandler, the method #handle(ResultSet) calls #handleRow(ResultSet) for each row in the ResultSet,
        which in the case of a BeanListHandler, calls RowProcessor#toBean(ResultSet, Class),
        which itself calls BeanProcessor#toBean(ResultSet, Class).

        A very simple way to make the BeanListHandler#handle(ResultSet) method faster is to override the GenericListHandler#handle(ResultSet) method by this code:

        {code}
            public Object handle(ResultSet rs) throws SQLException {
                return this.convert.toBeanList(rs, type);
            }
        {code}

        This way, the code I showed would be called only once, as it would not call BeanProcessor#toBean(ResultSet, Class) for each row but BeanProcessor#toBeanList(ResultSet, Class).
        Henri Yandell made changes -
        Status Open [ 1 ] Closed [ 6 ]
        Fix Version/s 1.2 [ 12312139 ]
        Resolution Fixed [ 1 ]
        Dan Fabulich made changes -
        Assignee Dan Fabulich [ dfabulich ]

          People

          • Assignee:
            Dan Fabulich
            Reporter:
            Julien Aymé
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development