Your SlideShare is downloading. ×
0
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Generating Power with Yield
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Generating Power with Yield

768

Published on

My talk for the Nashville PHP Users Group August 2013 meeting. …

My talk for the Nashville PHP Users Group August 2013 meeting.

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
768
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Generating Power with Yield/Jason Myers @jasonamyers
  • 2. Yield, a modern language love story Originally Proposed in 1995, the yield keyword became official via the RFP on June 20th 2013 with PHP 5.5.Generators Facebook said a Hip, Hop and Don't Stop, and did their own yield generators in HipHop PHP
  • 3. They are HEAVILY BASED off of Python, with a nod towards the Mozilla JS implementation and the await C# concept.
  • 4. Iterator An object that lets us traverse a container
  • 5. PHP Iterator Interface Iterator extends Traversable { /* Methods */ abstract public mixed current ( void ) abstract public scalar key ( void ) abstract public void next ( void ) abstract public void rewind ( void ) abstract public boolean valid ( void ) } For example checkout classArrayIterator
  • 6. ArrayIterator Example $fruits = array( "apple" => "yummy", "orange" => "ah ya, nice", "grape" => "wow, I love it!", "plum" => "nah, not me" ); $obj = new ArrayObject( $fruits ); $it = $obj->getIterator(); echo "Iterating over: " . $obj->count() . " valuesn"; while( $it->valid() ) { echo $it->key() . "=" . $it->current() . "n"; $it->next(); } Iterating over: 4 values apple=yummy orange=ah ya, nice grape=wow, I love it! plum=nah, not me
  • 7. Generator a special routine that can be used to control the iteration behavior of a loop, and yields the values one at a time
  • 8. TL;DR A generator looks like a function but behaves like an iterator
  • 9. Performant? range(0, 1000000) Uses over 100MB of RAM
  • 10. Generator Version function xrange($start, $limit, $step = 1) { if ($start < $limit) { if ($step <= 0) { throw new LogicException('Step must be +ve'); } for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } else { if ($step >= 0) { throw new LogicException('Step must be -ve'); } for ($i = $start; $i >= $limit; $i += $step) { yield $i; } } } uses less than 1KB!
  • 11. TL; DR function xrange($min, $max) { for ($i = $min; $i < $max; $i++) { yield $i; } }
  • 12. Sequences function collatz($val) { yield $val; while ($val != 1) { if ($val%2 == 0) { $val /= 2; } else { $val = 3*$val + 1; } yield $val; } } foreach (collatz(11) as $c) { echo $c," "; } 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
  • 13. Y U Only LOOPin? It will work for any function that takes an Iterator or a Traversable as argument $arr = iterator_to_array(collatz(11));
  • 14. Transformations function multiply_sequence($a, $fac) { foreach ($a as $val) { yield $val*$fac; } } function to_html_list($input) { foreach ($input as $val) { yield "<li>".$val."</li>"; } }
  • 15. Chaining foreach (to_html_list(multiply_sequence(collatz(5),2)) as $val) { echo $val,"n"; } <li>10</li> <li>32</li> <li>16</li> <li>8</li> <li>4</li> <li>2</li>
  • 16. Selections function select_pattern($input, $pattern) { foreach ($input as $val) { if (preg_match($pattern, $val)) { yield $val; } } }
  • 17. Breath In function getLines($file) { $f = fopen($file, 'r'); if (!$f) { throw new Exception(); } while ($line = fgets($f)) { yield $line; } fclose($f); } foreach (getLines("someFile") as $line) { doSomethingWithLine($line); }
  • 18. Breath Out function createLog($file) { $f = fopen($file, 'a'); while (true) { $line = yield; fwrite($f, $line); } } $log = createLog($file); $log->send("First"); $log->send("Second"); $log->send("Third");
  • 19. Bro Remote Me! Fake the simultaneous processing of data
  • 20. Green Threads threads that are scheduled by a virtual machine (VM/interperter?) instead of natively by the underlying operating system
  • 21. function step1() { $f = fopen("file.txt", 'r'); while ($line = fgets($f)) { processLine($line); yield true; } }
  • 22. function step2() { $f = fopen("file2.txt", 'r'); while ($line = fgets($f)) { processLine($line); yield true; } }
  • 23. function step3() { $f = fsockopen("www.example.com", 80); stream_set_blocking($f, false); $headers = "GET / HTTP/1.1rn"; $headers .= "Host: www.example.comrn"; $headers .= "Connection: Closernrn"; fwrite($f, $headers); $body = ''; while (!feof($f)) { $body .= fread($f, 8192); yield true; } processBody($body); }
  • 24. function runner(array $steps) { while (true) { foreach ($steps as $key => $step) { $step->next(); if (!$step->valid()) { unset($steps[$key]); } } if (empty($steps)) return; } } runner(array(step1(), step2(), step3()));
  • 25. ZOMG... THERE BE DRAGONS! This relies on making sure we have no blocking IO
  • 26. overREACTPHP much? event based, non-blocking IO - ReActPHP
  • 27. One More Thing So if I can flip control, I can haz an Async?
  • 28. class Buffer { protected $reads, $data; public function __construct() { $this->reads = new SplQueue(); $this->data = new SplQueue(); } public function read() { if( $this->data->isEmpty() ) { $deferred = new ReactPromiseDeferred(); $this->reads->enqueue($deferred->resolver()); return $deferred->promise(); } else { return ReactPromiseWhen::resolve($this->data->dequeue()); } } public function write($str) { if( $this->reads->isEmpty() ) { $this->data->enqueue($str); } else { $this->reads->dequeue()->resolve($str); } } }
  • 29. function printer(Buffer $buffer) { while( true ) { $value = ( yield Util::async($buffer->read()) ); echo "Printer: ", $value, PHP_EOL; yield Util::async(nested_printer($buffer)); } }
  • 30. function nested_printer(Buffer $buffer) { for( $i = 0; $i < 5; $i++ ) { // Yield a promise task and wait for the result - this is non-blocking $value = ( yield Util::async($buffer->read()) ); echo "Nested printer: ", $value, PHP_EOL; } }
  • 31. $buffer = new Buffer(); $scheduler = new AsyncScheduler(); $scheduler->add(new AsyncTaskGeneratorTask(printer($buffer))); $i = 0; $scheduler->add(new AsyncTaskRecurringTask( function() use($buffer, &$i) { $buffer->write(++$i); } )); $scheduler->run(); Printer: 1 Nested printer: 2 Nested printer: 3 Nested printer: 4 Nested printer: 5 Nested printer: 6 Printer: 7 Nested printer: 8 Nested printer: 9 Nested printer: 10 Nested printer: 11 Nested printer: 12 ...
  • 32. $loop = ReactEventLoopFactory::create(); $scheduler = new AsyncScheduler(); $scheduler->add(new AsyncTaskRecurringTask([$loop, 'tick'])); $scheduler->run();
  • 33. Async Created by Matt Pryor, on Bitbucket
  • 34. Thanks Huge thanks to Paul M. Jones and William Golden!
  • 35. THE END @jasonamyers

×