Skip to content

Commit

Permalink
Optimize combinators for resolved cases
Browse files Browse the repository at this point in the history
This implements three optimizations, for three different combinators.

For Future::all, if a future is already known to be failed, we know
upfront that the result will be a failed future, and we can reuse this
result.

For Future::after, if a future is already resolved, there is no reason
to keep it in the waiting list.

For Future::first, if a future is already known to be resolved, we know
upfront that the result will be a resolved future, and we can reuse this
result.

The implementations rely on `resolved?` and `failed?`, which according
to the specs are not guaranteed to exist on a future, and thus the code
has to check their presence before doing anything about it.
  • Loading branch information
grddev committed Oct 21, 2015
1 parent 878c4ab commit 8f82379
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/ione/future.rb
Expand Up @@ -209,6 +209,8 @@ def all(*futures)
end
if futures.count == 0
resolved([])
elsif (failed = futures.find { |f| f.respond_to?(:failed?) && f.failed? })
failed
else
CombinedFuture.new(futures)
end
Expand All @@ -231,6 +233,7 @@ def after(*futures)
if futures.size == 1 && (fs = futures.first).is_a?(Enumerable)
*futures = *fs
end
futures.reject! { |f| f.respond_to?(:resolved?) && f.resolved? }
if futures.count == 0
ResolvedFuture::NIL
elsif futures.count == 1
Expand Down Expand Up @@ -262,7 +265,9 @@ def first(*futures)
futures = fs
end
if futures.count == 0
resolved
ResolvedFuture::NIL
elsif (done = futures.find { |f| f.respond_to?(:resolved?) && f.resolved? })
done
else
FirstFuture.new(futures)
end
Expand Down

0 comments on commit 8f82379

Please sign in to comment.