Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>That's what <code>Futures</code> was made for. Just <code>import scala.actors.Futures._</code>, use <code>future</code> to create new futures, methods like <code>awaitAll</code> to wait on the results for a while, <code>apply</code> or <code>respond</code> to block until the result is received, <code>isSet</code> to see if it's ready or not, etc.</p> <p>You don't need to create a thread pool either. Or, at least, not normally you don't. Why do you think you do?</p> <p><strong>EDIT</strong></p> <p>You can't gain performance parallelizing something as simple as an integer addition, because that's even faster than a function call. Concurrency will only bring performance by avoiding time lost to blocking i/o and by using multiple CPU cores to execute tasks in parallel. In the latter case, the task must be computationally expensive enough to offset the cost of dividing the workload and merging the results.</p> <p>One other reason to go for concurrency is to improve the <em>responsiveness</em> of the application. That's not making it faster, that's making it respond faster to the user, and one way of doing that is getting even relatively fast operations offloaded to another thread so that the threads handling what the user sees or does can be faster. But I digress.</p> <p>There's a serious problem with your code:</p> <pre><code> def paraAdd(hi: Int) = (0 until hi) map (i=&gt;exec(i+5)) foreach (_.get) def singAdd(hi: Int) = (0 until hi) foreach (i=&gt;i+5) </code></pre> <p>Or, translating into futures,</p> <pre><code> def paraAdd(hi: Int) = (0 until hi) map (i=&gt;future(i+5)) foreach (_.apply) def singAdd(hi: Int) = (0 until hi) foreach (i=&gt;i+5) </code></pre> <p>You might think <code>paraAdd</code> is doing the tasks in paralallel, but it isn't, because <code>Range</code> has a non-strict implementation of <code>map</code> (that's up to Scala 2.7; starting with Scala 2.8.0, <code>Range</code> is strict). You can look it up on other Scala questions. What happens is this:</p> <ol> <li>A range is created from <code>0</code> until <code>hi</code></li> <li>A range projection is created from each element i of the range into a function that returns <code>future(i+5)</code> when called.</li> <li>For each element of the range projection (<code>i =&gt; future(i+5))</code>, the element is evaluated (<code>foreach</code> is strict) and then the function <code>apply</code> is called on it.</li> </ol> <p>So, because <code>future</code> is <em>not</em> called in step 2, but only in step 3, you'll wait for each <code>future</code> to complete before doing the next one. You can fix it with:</p> <pre><code> def paraAdd(hi: Int) = (0 until hi).force map (i=&gt;future(i+5)) foreach (_.apply) </code></pre> <p>Which will give you better performance, but never as good as a simple immediate addition. On the other hand, suppose you do this:</p> <pre><code>def repeat(n: Int, f: =&gt; Any) = (0 until n) foreach (_ =&gt; f) def paraRepeat(n: Int, f: =&gt; Any) = (0 until n).force map (_ =&gt; future(f)) foreach (_.apply) </code></pre> <p>And then compare:</p> <pre><code>cmp(repeat(100, singAdd(100000)), paraRepeat(100, singAdd(100000))) </code></pre> <p>You may start seeing gains (it will depend on the number of cores and processor speed).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload