Поведение конвейера оператора подачи - PullRequest
5 голосов
/ 15 марта 2019

Я экспериментирую с оператором подачи, используя следующий код:

my $limit=10000000;
my $list=(0,1...4);
sub task($_,$name) {
    say "Start $name on $*THREAD";
    loop ( my $i=0; $i < $limit; $i++ ){};
    say "End $name";
    Nil;
}

sub stage( &code, *@elements --> Seq) {
    map(&code,  @elements);
}

sub feeds() {
    my @results;
    $list
    ==> map ({ task($_, "stage 1"); say( now - ENTER now );$_+1})
    ==> map ({ task($_, "stage 2"); say( now - ENTER now );$_+1})
    ==> stage ({ task($_, "stage 3"); say( now - ENTER now );$_+1}) 
    ==> @results;

    say @results;
}

feeds();
  • подпрограмма task - это просто цикл для записи циклов процессора и отображает используемый поток
  • подпрограмма stage представляет собой обертку вокруг подпрограммы map
  • . Каждый шаг конвейера подачи соответствует вызову задачи с интенсивным использованием процессора и ее синхронизации.Результатом карты является ввод + 1

Выход при запуске:

Start stage 1 on Thread<1>(Initial thread)
End stage 1
0.7286811
Start stage 2 on Thread<1>(Initial thread)
End stage 2
0.59053989
Start stage 1 on Thread<1>(Initial thread)
End stage 1
0.5955893
Start stage 2 on Thread<1>(Initial thread)
End stage 2
0.59050998
Start stage 1 on Thread<1>(Initial thread)
End stage 1
0.59472201
Start stage 2 on Thread<1>(Initial thread)
End stage 2
0.5968531
Start stage 1 on Thread<1>(Initial thread)
End stage 1
0.5917188
Start stage 2 on Thread<1>(Initial thread)
End stage 2
0.587358
Start stage 1 on Thread<1>(Initial thread)
End stage 1
0.58689858
Start stage 2 on Thread<1>(Initial thread)
End stage 2
0.59177099
Start stage 3 on Thread<1>(Initial thread)
End stage 3
3.8549498
Start stage 3 on Thread<1>(Initial thread)
End stage 3
3.8560015
Start stage 3 on Thread<1>(Initial thread)
End stage 3
3.77634317
Start stage 3 on Thread<1>(Initial thread)
End stage 3
3.6754558
Start stage 3 on Thread<1>(Initial thread)
End stage 3
3.672909
[3 4 5 6 7]

Результат в @result верный (Ввод из $list вувеличен на 3 три раза)

Выход первых двух каскадов тянется / чередуется, но третий каскад не выполняется до завершения всех входов в каскад 2

Есть ли проблема смоя оболочка к карте sub вызывает такое поведение?

Кроме того, время, необходимое для оценки в оболочке, значительно больше, чем прямой вызов карты.

Любая помощь приветствуется.

1 Ответ

6 голосов
/ 15 марта 2019

Параметр slurpy ожидает получения всей передаваемой ему последовательности.Рассмотрим разницу между:

perl6 -e 'sub foo($) { }; my $items := gather for 1..Inf { say $_ }; foo($items);'
perl6 -e 'sub foo(*@) { }; my $items := gather for 1..Inf { say $_ }; foo($items);'

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

sub stage( &code, $elements --> Seq) {
    map(&code,  $elements);
}
...