Optimising multiple streams to single loop

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I am trying to find the best way to optimise the converters below to first follow the flow I call convertAndGroupForUpdate, which triggers the conversions and relevant mappings.



Any help to optimise this code would be massively appreciated.



public List<GroupedOrderActionUpdateEntity> convertAndGroupForUpdate(List<SimpleRatifiableAction> actions) 
List<GroupedOrderActionUpdateEntity> groupedActions = new ArrayList<>();

Map<String, List<SimpleRatifiableAction>> groupSimple = actions.stream()
.collect(Collectors.groupingBy(x -> x.getOrderNumber() + x.getActionType()));

groupSimple.entrySet().stream()
.map(x -> convertToUpdateGroup(x.getValue()))
.forEachOrdered(groupedActions::add);

return groupedActions;


public GroupedOrderActionUpdateEntity convertToUpdateGroup(List<SimpleRatifiableAction> actions)
List<OrderActionUpdateEntity> actionList = actions.stream().map(x -> convertToUpdateEntity(x)).collect(Collectors.toList());

return new GroupedOrderActionUpdateEntity(
actions.get(0).getOrderNumber(),
OrderActionType.valueOf(actions.get(0).getActionType()),
actions.get(0).getSource(),
12345,
actions.stream().map(SimpleRatifiableAction::getNote)
.collect(Collectors.joining(", ", "Group Order Note: ", ".")),
actionList);


public OrderActionUpdateEntity convertToUpdateEntity(SimpleRatifiableAction action)
return new OrderActionUpdateEntity(action.getId(), OrderActionState.valueOf(action.getState()));







share|improve this question





















  • It should be already fast, without any changes required. some changes might make code cleaner but not faster. Is actionslist fetched from database? Then performance issue might be caused by lazy loading and stackoverflow.com/a/2764474/158037 .
    – user158037
    Mar 22 at 13:15
















up vote
2
down vote

favorite












I am trying to find the best way to optimise the converters below to first follow the flow I call convertAndGroupForUpdate, which triggers the conversions and relevant mappings.



Any help to optimise this code would be massively appreciated.



public List<GroupedOrderActionUpdateEntity> convertAndGroupForUpdate(List<SimpleRatifiableAction> actions) 
List<GroupedOrderActionUpdateEntity> groupedActions = new ArrayList<>();

Map<String, List<SimpleRatifiableAction>> groupSimple = actions.stream()
.collect(Collectors.groupingBy(x -> x.getOrderNumber() + x.getActionType()));

groupSimple.entrySet().stream()
.map(x -> convertToUpdateGroup(x.getValue()))
.forEachOrdered(groupedActions::add);

return groupedActions;


public GroupedOrderActionUpdateEntity convertToUpdateGroup(List<SimpleRatifiableAction> actions)
List<OrderActionUpdateEntity> actionList = actions.stream().map(x -> convertToUpdateEntity(x)).collect(Collectors.toList());

return new GroupedOrderActionUpdateEntity(
actions.get(0).getOrderNumber(),
OrderActionType.valueOf(actions.get(0).getActionType()),
actions.get(0).getSource(),
12345,
actions.stream().map(SimpleRatifiableAction::getNote)
.collect(Collectors.joining(", ", "Group Order Note: ", ".")),
actionList);


public OrderActionUpdateEntity convertToUpdateEntity(SimpleRatifiableAction action)
return new OrderActionUpdateEntity(action.getId(), OrderActionState.valueOf(action.getState()));







share|improve this question





















  • It should be already fast, without any changes required. some changes might make code cleaner but not faster. Is actionslist fetched from database? Then performance issue might be caused by lazy loading and stackoverflow.com/a/2764474/158037 .
    – user158037
    Mar 22 at 13:15












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I am trying to find the best way to optimise the converters below to first follow the flow I call convertAndGroupForUpdate, which triggers the conversions and relevant mappings.



Any help to optimise this code would be massively appreciated.



public List<GroupedOrderActionUpdateEntity> convertAndGroupForUpdate(List<SimpleRatifiableAction> actions) 
List<GroupedOrderActionUpdateEntity> groupedActions = new ArrayList<>();

Map<String, List<SimpleRatifiableAction>> groupSimple = actions.stream()
.collect(Collectors.groupingBy(x -> x.getOrderNumber() + x.getActionType()));

groupSimple.entrySet().stream()
.map(x -> convertToUpdateGroup(x.getValue()))
.forEachOrdered(groupedActions::add);

return groupedActions;


public GroupedOrderActionUpdateEntity convertToUpdateGroup(List<SimpleRatifiableAction> actions)
List<OrderActionUpdateEntity> actionList = actions.stream().map(x -> convertToUpdateEntity(x)).collect(Collectors.toList());

return new GroupedOrderActionUpdateEntity(
actions.get(0).getOrderNumber(),
OrderActionType.valueOf(actions.get(0).getActionType()),
actions.get(0).getSource(),
12345,
actions.stream().map(SimpleRatifiableAction::getNote)
.collect(Collectors.joining(", ", "Group Order Note: ", ".")),
actionList);


public OrderActionUpdateEntity convertToUpdateEntity(SimpleRatifiableAction action)
return new OrderActionUpdateEntity(action.getId(), OrderActionState.valueOf(action.getState()));







share|improve this question













I am trying to find the best way to optimise the converters below to first follow the flow I call convertAndGroupForUpdate, which triggers the conversions and relevant mappings.



Any help to optimise this code would be massively appreciated.



public List<GroupedOrderActionUpdateEntity> convertAndGroupForUpdate(List<SimpleRatifiableAction> actions) 
List<GroupedOrderActionUpdateEntity> groupedActions = new ArrayList<>();

Map<String, List<SimpleRatifiableAction>> groupSimple = actions.stream()
.collect(Collectors.groupingBy(x -> x.getOrderNumber() + x.getActionType()));

groupSimple.entrySet().stream()
.map(x -> convertToUpdateGroup(x.getValue()))
.forEachOrdered(groupedActions::add);

return groupedActions;


public GroupedOrderActionUpdateEntity convertToUpdateGroup(List<SimpleRatifiableAction> actions)
List<OrderActionUpdateEntity> actionList = actions.stream().map(x -> convertToUpdateEntity(x)).collect(Collectors.toList());

return new GroupedOrderActionUpdateEntity(
actions.get(0).getOrderNumber(),
OrderActionType.valueOf(actions.get(0).getActionType()),
actions.get(0).getSource(),
12345,
actions.stream().map(SimpleRatifiableAction::getNote)
.collect(Collectors.joining(", ", "Group Order Note: ", ".")),
actionList);


public OrderActionUpdateEntity convertToUpdateEntity(SimpleRatifiableAction action)
return new OrderActionUpdateEntity(action.getId(), OrderActionState.valueOf(action.getState()));









share|improve this question












share|improve this question




share|improve this question








edited Mar 23 at 18:22









smac89

1,278619




1,278619









asked Mar 22 at 12:21









Kieran Wild

111




111











  • It should be already fast, without any changes required. some changes might make code cleaner but not faster. Is actionslist fetched from database? Then performance issue might be caused by lazy loading and stackoverflow.com/a/2764474/158037 .
    – user158037
    Mar 22 at 13:15
















  • It should be already fast, without any changes required. some changes might make code cleaner but not faster. Is actionslist fetched from database? Then performance issue might be caused by lazy loading and stackoverflow.com/a/2764474/158037 .
    – user158037
    Mar 22 at 13:15















It should be already fast, without any changes required. some changes might make code cleaner but not faster. Is actionslist fetched from database? Then performance issue might be caused by lazy loading and stackoverflow.com/a/2764474/158037 .
– user158037
Mar 22 at 13:15




It should be already fast, without any changes required. some changes might make code cleaner but not faster. Is actionslist fetched from database? Then performance issue might be caused by lazy loading and stackoverflow.com/a/2764474/158037 .
– user158037
Mar 22 at 13:15










1 Answer
1






active

oldest

votes

















up vote
0
down vote













Specifying a downstream Collector for Collectors.groupingBy



There is an alternative Collectors.groupingBy(Function, Collector) method that lets you specify further steps that you want to do with the intermediary List<SimpleRatifiableAction> values after the grouping.



Then, with a bit of renaming, some help from method references, plus some convenience methods like having a SimpleRatifiableAction.getKey():



public String getKey() 
return getOrderNumber() + getActionType();



You can have a method that reads:



// dropping method visibility modifier for brevity
List<GroupedOrderActionUpdateEntity> process(List<SimpleRatifiableAction> actions)
return new ArrayList<>(actions.stream()
.collect(Collectors.groupingBy(SimpleRatifiableAction::getKey,
Collectors.collectingAndThen(Collectors.toList(),
this::createUpdateEntity)))
.values());



Looping once, aggregating multiple values



Inside convertToUpdateGroup(List), now renamed as createUpdateEntity(List), you are streaming twice on the List argument. While this shouldn't be an issue for most cases, there is still an option to just loop once should it be one of the remaining places to optimize (hopefully with some runtime analysis/micro-benchmarking to prove it).



This is achieved by creating the StringJoiner instance yourself (instead of relying on Collectors.joining()). To avoid similar List.get(0) calls, you can also get a reference to it once.



Putting it altogether:



// dropping method visibility modifier for brevity
GroupedOrderActionUpdateEntity createUpdateEntity(List<SimpleRatifiableAction> actions)
SimpleRatifiableAction first = actions.get(0);
StringJoiner joiner = new StringJoiner(", ", "Group Order Note: ", ".");
List<OrderActionUpdateEntity> updateEntities = new ArrayList<>();
actions.forEach(v ->
joiner.add(v.getNote());
updateEntities.add(v.createUpdateEntity());
);
return new GroupedOrderActionUpdateEntity(
first.getOrderNumber(),
OrderActionType.valueOf(first.getActionType()),
first.getSource(),
12345,
joiner.toString(),
updateEntities);



SimpleRatifiableAction.createUpdateEntity() is also another convenience method that you can consider:



public OrderActionUpdateEntity createUpdateEntity() 
return new OrderActionUpdateEntity(getId(), OrderActionState.valueOf(getState()));






share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190198%2foptimising-multiple-streams-to-single-loop%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    Specifying a downstream Collector for Collectors.groupingBy



    There is an alternative Collectors.groupingBy(Function, Collector) method that lets you specify further steps that you want to do with the intermediary List<SimpleRatifiableAction> values after the grouping.



    Then, with a bit of renaming, some help from method references, plus some convenience methods like having a SimpleRatifiableAction.getKey():



    public String getKey() 
    return getOrderNumber() + getActionType();



    You can have a method that reads:



    // dropping method visibility modifier for brevity
    List<GroupedOrderActionUpdateEntity> process(List<SimpleRatifiableAction> actions)
    return new ArrayList<>(actions.stream()
    .collect(Collectors.groupingBy(SimpleRatifiableAction::getKey,
    Collectors.collectingAndThen(Collectors.toList(),
    this::createUpdateEntity)))
    .values());



    Looping once, aggregating multiple values



    Inside convertToUpdateGroup(List), now renamed as createUpdateEntity(List), you are streaming twice on the List argument. While this shouldn't be an issue for most cases, there is still an option to just loop once should it be one of the remaining places to optimize (hopefully with some runtime analysis/micro-benchmarking to prove it).



    This is achieved by creating the StringJoiner instance yourself (instead of relying on Collectors.joining()). To avoid similar List.get(0) calls, you can also get a reference to it once.



    Putting it altogether:



    // dropping method visibility modifier for brevity
    GroupedOrderActionUpdateEntity createUpdateEntity(List<SimpleRatifiableAction> actions)
    SimpleRatifiableAction first = actions.get(0);
    StringJoiner joiner = new StringJoiner(", ", "Group Order Note: ", ".");
    List<OrderActionUpdateEntity> updateEntities = new ArrayList<>();
    actions.forEach(v ->
    joiner.add(v.getNote());
    updateEntities.add(v.createUpdateEntity());
    );
    return new GroupedOrderActionUpdateEntity(
    first.getOrderNumber(),
    OrderActionType.valueOf(first.getActionType()),
    first.getSource(),
    12345,
    joiner.toString(),
    updateEntities);



    SimpleRatifiableAction.createUpdateEntity() is also another convenience method that you can consider:



    public OrderActionUpdateEntity createUpdateEntity() 
    return new OrderActionUpdateEntity(getId(), OrderActionState.valueOf(getState()));






    share|improve this answer

























      up vote
      0
      down vote













      Specifying a downstream Collector for Collectors.groupingBy



      There is an alternative Collectors.groupingBy(Function, Collector) method that lets you specify further steps that you want to do with the intermediary List<SimpleRatifiableAction> values after the grouping.



      Then, with a bit of renaming, some help from method references, plus some convenience methods like having a SimpleRatifiableAction.getKey():



      public String getKey() 
      return getOrderNumber() + getActionType();



      You can have a method that reads:



      // dropping method visibility modifier for brevity
      List<GroupedOrderActionUpdateEntity> process(List<SimpleRatifiableAction> actions)
      return new ArrayList<>(actions.stream()
      .collect(Collectors.groupingBy(SimpleRatifiableAction::getKey,
      Collectors.collectingAndThen(Collectors.toList(),
      this::createUpdateEntity)))
      .values());



      Looping once, aggregating multiple values



      Inside convertToUpdateGroup(List), now renamed as createUpdateEntity(List), you are streaming twice on the List argument. While this shouldn't be an issue for most cases, there is still an option to just loop once should it be one of the remaining places to optimize (hopefully with some runtime analysis/micro-benchmarking to prove it).



      This is achieved by creating the StringJoiner instance yourself (instead of relying on Collectors.joining()). To avoid similar List.get(0) calls, you can also get a reference to it once.



      Putting it altogether:



      // dropping method visibility modifier for brevity
      GroupedOrderActionUpdateEntity createUpdateEntity(List<SimpleRatifiableAction> actions)
      SimpleRatifiableAction first = actions.get(0);
      StringJoiner joiner = new StringJoiner(", ", "Group Order Note: ", ".");
      List<OrderActionUpdateEntity> updateEntities = new ArrayList<>();
      actions.forEach(v ->
      joiner.add(v.getNote());
      updateEntities.add(v.createUpdateEntity());
      );
      return new GroupedOrderActionUpdateEntity(
      first.getOrderNumber(),
      OrderActionType.valueOf(first.getActionType()),
      first.getSource(),
      12345,
      joiner.toString(),
      updateEntities);



      SimpleRatifiableAction.createUpdateEntity() is also another convenience method that you can consider:



      public OrderActionUpdateEntity createUpdateEntity() 
      return new OrderActionUpdateEntity(getId(), OrderActionState.valueOf(getState()));






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        Specifying a downstream Collector for Collectors.groupingBy



        There is an alternative Collectors.groupingBy(Function, Collector) method that lets you specify further steps that you want to do with the intermediary List<SimpleRatifiableAction> values after the grouping.



        Then, with a bit of renaming, some help from method references, plus some convenience methods like having a SimpleRatifiableAction.getKey():



        public String getKey() 
        return getOrderNumber() + getActionType();



        You can have a method that reads:



        // dropping method visibility modifier for brevity
        List<GroupedOrderActionUpdateEntity> process(List<SimpleRatifiableAction> actions)
        return new ArrayList<>(actions.stream()
        .collect(Collectors.groupingBy(SimpleRatifiableAction::getKey,
        Collectors.collectingAndThen(Collectors.toList(),
        this::createUpdateEntity)))
        .values());



        Looping once, aggregating multiple values



        Inside convertToUpdateGroup(List), now renamed as createUpdateEntity(List), you are streaming twice on the List argument. While this shouldn't be an issue for most cases, there is still an option to just loop once should it be one of the remaining places to optimize (hopefully with some runtime analysis/micro-benchmarking to prove it).



        This is achieved by creating the StringJoiner instance yourself (instead of relying on Collectors.joining()). To avoid similar List.get(0) calls, you can also get a reference to it once.



        Putting it altogether:



        // dropping method visibility modifier for brevity
        GroupedOrderActionUpdateEntity createUpdateEntity(List<SimpleRatifiableAction> actions)
        SimpleRatifiableAction first = actions.get(0);
        StringJoiner joiner = new StringJoiner(", ", "Group Order Note: ", ".");
        List<OrderActionUpdateEntity> updateEntities = new ArrayList<>();
        actions.forEach(v ->
        joiner.add(v.getNote());
        updateEntities.add(v.createUpdateEntity());
        );
        return new GroupedOrderActionUpdateEntity(
        first.getOrderNumber(),
        OrderActionType.valueOf(first.getActionType()),
        first.getSource(),
        12345,
        joiner.toString(),
        updateEntities);



        SimpleRatifiableAction.createUpdateEntity() is also another convenience method that you can consider:



        public OrderActionUpdateEntity createUpdateEntity() 
        return new OrderActionUpdateEntity(getId(), OrderActionState.valueOf(getState()));






        share|improve this answer













        Specifying a downstream Collector for Collectors.groupingBy



        There is an alternative Collectors.groupingBy(Function, Collector) method that lets you specify further steps that you want to do with the intermediary List<SimpleRatifiableAction> values after the grouping.



        Then, with a bit of renaming, some help from method references, plus some convenience methods like having a SimpleRatifiableAction.getKey():



        public String getKey() 
        return getOrderNumber() + getActionType();



        You can have a method that reads:



        // dropping method visibility modifier for brevity
        List<GroupedOrderActionUpdateEntity> process(List<SimpleRatifiableAction> actions)
        return new ArrayList<>(actions.stream()
        .collect(Collectors.groupingBy(SimpleRatifiableAction::getKey,
        Collectors.collectingAndThen(Collectors.toList(),
        this::createUpdateEntity)))
        .values());



        Looping once, aggregating multiple values



        Inside convertToUpdateGroup(List), now renamed as createUpdateEntity(List), you are streaming twice on the List argument. While this shouldn't be an issue for most cases, there is still an option to just loop once should it be one of the remaining places to optimize (hopefully with some runtime analysis/micro-benchmarking to prove it).



        This is achieved by creating the StringJoiner instance yourself (instead of relying on Collectors.joining()). To avoid similar List.get(0) calls, you can also get a reference to it once.



        Putting it altogether:



        // dropping method visibility modifier for brevity
        GroupedOrderActionUpdateEntity createUpdateEntity(List<SimpleRatifiableAction> actions)
        SimpleRatifiableAction first = actions.get(0);
        StringJoiner joiner = new StringJoiner(", ", "Group Order Note: ", ".");
        List<OrderActionUpdateEntity> updateEntities = new ArrayList<>();
        actions.forEach(v ->
        joiner.add(v.getNote());
        updateEntities.add(v.createUpdateEntity());
        );
        return new GroupedOrderActionUpdateEntity(
        first.getOrderNumber(),
        OrderActionType.valueOf(first.getActionType()),
        first.getSource(),
        12345,
        joiner.toString(),
        updateEntities);



        SimpleRatifiableAction.createUpdateEntity() is also another convenience method that you can consider:



        public OrderActionUpdateEntity createUpdateEntity() 
        return new OrderActionUpdateEntity(getId(), OrderActionState.valueOf(getState()));







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Mar 23 at 16:15









        h.j.k.

        18.1k32490




        18.1k32490






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f190198%2foptimising-multiple-streams-to-single-loop%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Greedy Best First Search implementation in Rust

            Function to Return a JSON Like Objects Using VBA Collections and Arrays

            C++11 CLH Lock Implementation