Skip to content

Commit a26e675

Browse files
authored
Update README.MD
1 parent 08d3db3 commit a26e675

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

README.MD

+12-10
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,24 @@ With this library you can:
66
* Seamlessly integrate with Task-based and async APIs
77
* Integrate with IEnumerator-based coroutines and YieldInstructions
88
* Easily switch sync contexts (main to background and vice-versa)
9-
* Define your own custom await instructions (allocation free)
9+
* Define your own custom await instructions (allocation free, no boxing!)
1010
* Return results at the end of your coroutine
1111
# Performance
12-
Rest assured; UnityAsync coroutines will generally always perform better than Unity's built-in coroutines because:
12+
Rest assured; UnityAsync coroutines will generally perform better than Unity's built-in coroutines because:
1313
* They rarely cause heap allocations
1414
* They don't weave in and out of native code
1515
* They don't rely on a monolithic state machine
1616

17-
Benchmarks with 100,000 simultaneous update loop coroutines show a performance increase of over 150% (that's 2.5x), and this doesn't test against `YieldInstructions`. A test with uncached `WaitForSeconds` using a random number as input yields a performance increase of over 290% (3.9x). The benchmarks included the time it took to instantiate the coroutines.
17+
Comparing with standard `yield return null` update loops, performance is 150% improved. Uncached `WaitForSeconds` loops yield a performance increase of over 290%. The benchmarks included the time it took to instantiate the coroutines.
1818

19-
The single downside is that if you want to nest multiple coroutines inside each other, you must store a reference to them, which means returning a `Task` object. This causes a 336 byte heap allocation, whereas Unity's coroutines allocate less memory (but they still allocate on the heap). This often isn't a problem because nested coroutines rarely execute in their entirety every frame and these allocations are still tiny.
19+
The one caveat is, in order to store the coroutine, a `Task` object must be allocated. A `Task` object is a bigger allocation compared to a `Coroutine` object. No way around it, if you want to integrate with `Task`-based APIs, you need to use `Tasks`. Often, you just need to fire the coroutine and forget about it, and in such cases, simply use `void` return type to avoid allocations altogether.
2020

2121
# Usage
22+
## Installation
23+
Clone the repo into your assets folder or download the [latest release](https://github.com/muckSponge/UnityAsync/releases/latest) and open the .unitypackage.
24+
2225
## Replacing existing coroutines
23-
Let's say we want to replace a pretty straight-forward update loop IEnumerator coroutine:
26+
Let's say we want to replace a pretty straight-forward update loop `IEnumerator` coroutine:
2427
```c#
2528
using UnityEngine;
2629
using System.Collections;
@@ -41,7 +44,7 @@ void Start()
4144
...
4245

4346
```
44-
UnityAsync coroutines are defined by async methods, which can return void, `Task`, or `Task<TResult>`:
47+
UnityAsync coroutines are defined by async methods, which can return `void`, `Task`, or `Task<TResult>`:
4548
```c#
4649
using UnityEngine;
4750
using UnityAsync;
@@ -100,10 +103,10 @@ async void Start()
100103

101104
...
102105
```
103-
We are awaiting the result in Start so it needs to be an async method (this doesn't impact on how Unity calls it). We now return `Task<int>` and the result is available after 10 frames.
106+
We are awaiting the result in `Start()` so it needs to be an async method (this doesn't impact on how Unity calls it). We now return `Task<int>` and the result is available after 10 frames.
104107

105108
## Switching contexts
106-
Sometimes you'll want to perform some task on the thread pool and return to the main thread once this is completed without blocking. This could be done via `Task.ConfigureAwait` but now you can await directly on a `SynchronizationContext` which makes it super easy to swap back and forth:
109+
Sometimes you'll want to perform some task on the thread pool and return to the main thread once this is completed without blocking. This could be done via `Task.ConfigureAwait()` but now you can await directly on a `SynchronizationContext` which makes it super easy to swap back and forth:
107110
```c#
108111
using UnityAsync;
109112

@@ -161,6 +164,7 @@ async void Start()
161164
...
162165

163166
```
167+
164168
## Yielding a task
165169
You may run into a situation where some of your coroutine code is async, but it is called from an `IEnumerator`. In such a situation you can use `Task.AsYieldInstruction` or `Task<TResult>.AsYieldInstruction`.
166170
```c#
@@ -190,7 +194,6 @@ async Task WaitForMouse()
190194
```
191195

192196
# Await instructions / awaitables
193-
194197
Built-in:
195198
* `WaitForFrames`
196199
* `WaitForSeconds`
@@ -246,7 +249,6 @@ public struct WaitForTimeSpan : IAwaitInstruction
246249
```
247250

248251
# Usage with Unity EditorTests (unit tests with NUnit)
249-
250252
When running unit tests, `AsyncManager` is not automatically initialized. Call `AsyncManager.InitializeForEditorTests()` in your test OneTimeSetUp method, for example like this:
251253

252254
```c#

0 commit comments

Comments
 (0)