Изменить список - потоковый подход - PullRequest
0 голосов
/ 06 февраля 2019

Я хочу изменить список уже созданных объектов в потоке.Я реализовал три подхода, которые могут сделать это, но я не уверен в их производительности и возможном сокращении.

  1. Возврат того же объекта - не пустая трата времени на создание нового объекта, но объект изменчивый
  2. Создание нового объекта - параметр не изменяется, но для создания огромного объекта требуется много времени
  3. Изменить параметр - можно использовать только ForEach, без параллельного использования

Код ниже кода с поясняющими комментариями.

public class Test {

    public static void main(String[] args) {
        //Already created objects
        List<Foo> foos0 = Arrays.asList(new Foo("A"));

        //However I need to apply some modification on them, that is dependent on themselves

        //1. Returning same object
        List<Foo> foos1 = foos0.stream().map(Test::modifyValueByReturningSameObject).collect(Collectors.toList());

        //2. Creating new object
        List<Foo> foos2 = foos0.stream().map(Test::modifyValueByCreatingNewObject).collect(Collectors.toList());

        //3. Modifying param
        foos0.stream().forEach(Test::modifyValueByModifyingParam);
    }

    //Lets imagine that all methods below are somehow dependent on param Foo
    static Foo modifyValueByReturningSameObject(Foo foo) {
        foo.setValue("fieldValueDependentOnParamFoo");
        return foo;
    }

    static Foo modifyValueByCreatingNewObject(Foo foo) {
        Foo newFoo = new Foo("fieldValueDependentOnParamFoo");
        return newFoo;
    }

    static void modifyValueByModifyingParam(Foo foo) {
        foo.setValue("fieldValueDependentOnParamFoo");
        return;
    }
}

public class Foo {

    public String value;

    public Foo(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

Итак, вопрос в том, какой подход является наиболее потоковым?

РЕДАКТИРОВАТЬ: Под потоковым подходом я подразумеваю, что большинство преимуществ в смысле производительности.

EDIT2: 1. Какой функциональный подход?2. Что лучше в смысле производительности?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Различные подходы в вашем случае, скорее всего, не приведут к разнице в производительности.

Причина: оптимизация.Java не будет создавать новые классы и будет использовать прямой доступ к полям.Он может (и будет, если анализ предложит это) даже пропустить целую цепочку вызовов и заменить ее предварительно рассчитанным значением.Во время выполнения Java даже используется профилировщик для оптимизации и поиска горячих точек ...

Кроме того: Что касается производительности, в целом (в отдельных случаях это может отличаться) более важно создать простую структуру и помочь среде выполнения сделать правильные предположения.,Так что, если вы скрываете то, что делаете, в обычной «оптимизации» вручную, которая скрывает возможности оптимизации (множество веток / решений, ненужное закрепление, цепочка «неизвестных» методов ...) от времени выполнения, вы можете получить более медленный результат..

Для ясности и побочных эффектов (см. Также другой ответ) Я скорее использую версию, которая создает новые экземпляры.

0 голосов
/ 06 февраля 2019

javadoc утверждает, что потокам следует избегать побочных эффектов:

Побочные эффекты в поведенческих параметрах для операций с потоками, как правило, не приветствуются, поскольку они часто могут привести кнепреднамеренные нарушения требования о безгражданстве, а также другие угрозы безопасности потоков.

Итак, вам следует предпочесть решение, в котором вы создаете новые объекты, а не модифицируете существующие.

...