test different exercise layout - chap 14
This commit is contained in:
parent
3b8ffa5d40
commit
6a8b3ae160
@ -14,72 +14,9 @@ average number of items from this set that were drawn at least once.
|
||||
|
||||
Call the function running this simulation `boot`.
|
||||
|
||||
### Exercise 2
|
||||
|
||||
Now write a function `simboot` that takes parameters `n` and `k` and runs
|
||||
the simulation defined in the `boot` function `k` times. It should return
|
||||
a named tuple storing `k`, `n`, mean of produced values, and ends of
|
||||
approximated 95% confidence interval of the result.
|
||||
|
||||
Make this function single threaded. Check how long
|
||||
this function runs for `n=1000` and `k=1_000_000`.
|
||||
|
||||
### Exercise 3
|
||||
|
||||
Now rewrite this simulator to be multi threaded. Use 4 cores for benchmarking.
|
||||
Call the function `simbootT`. Check how long this function runs for `n=1000` and
|
||||
`k=1_000_000`.
|
||||
|
||||
### Exercise 4
|
||||
|
||||
Now rewrite `boot` and `simbootT` to perform less allocations. Achieve this by
|
||||
making sure that all allocated objects are passed to `boot` function (so that it
|
||||
does not do any allocations internally). Call these new functions `boot!` and
|
||||
`simbootT2`. You might need to use the `Threads.threadid` and `Threads.nthreads`
|
||||
functions.
|
||||
|
||||
### Exercise 5
|
||||
|
||||
Use either of the solutions we have developed in the previous exercises to
|
||||
create a web service taking `k` and `n` parameters and returning the values
|
||||
produced by `boot` functions and time to run the simulation. You might want to
|
||||
use the `@timed` macro in your solution.
|
||||
|
||||
Start the server.
|
||||
|
||||
### Exercise 6
|
||||
|
||||
Query the server started in the exercise 5 with
|
||||
the following parameters:
|
||||
* `k=1000` and `n=1000`
|
||||
* `k=1.5` and `n=1000`
|
||||
|
||||
### Exercise 7
|
||||
|
||||
Collect the data generated by a web service into the `df` data frame for
|
||||
`k = [10^i for i in 3:6]` and `n = [10^i for i in 1:3]`.
|
||||
|
||||
### Exercise 8
|
||||
|
||||
Replace the `value` column in the `df` data frame by its contents in-place.
|
||||
|
||||
### Exercise 9
|
||||
|
||||
Checks that execution time roughly scales proportionally to the product
|
||||
of `k` times `n`.
|
||||
|
||||
### Exercise 10
|
||||
|
||||
Plot the expected fraction of seen elements in the set as a function of
|
||||
`n` by `k` along with 95% confidence interval around these values.
|
||||
|
||||
# Solutions
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Show!</summary>
|
||||
|
||||
### Exercise 1
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution (there are many other approaches you could use):
|
||||
|
||||
@ -95,8 +32,22 @@ function boot(n::Integer)
|
||||
end
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 2
|
||||
|
||||
Now write a function `simboot` that takes parameters `n` and `k` and runs
|
||||
the simulation defined in the `boot` function `k` times. It should return
|
||||
a named tuple storing `k`, `n`, mean of produced values, and ends of
|
||||
approximated 95% confidence interval of the result.
|
||||
|
||||
Make this function single threaded. Check how long
|
||||
this function runs for `n=1000` and `k=1_000_000`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -123,8 +74,18 @@ julia> @time simboot(1000, 1_000_000)
|
||||
|
||||
We see that on my computer the run time is around 7 seconds.
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 3
|
||||
|
||||
Now rewrite this simulator to be multi threaded. Use 4 cores for benchmarking.
|
||||
Call the function `simbootT`. Check how long this function runs for `n=1000` and
|
||||
`k=1_000_000`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -153,8 +114,20 @@ julia> @time simbootT(1000, 1_000_000)
|
||||
|
||||
Indeed we see a significant performance improvement.
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 4
|
||||
|
||||
Now rewrite `boot` and `simbootT` to perform less allocations. Achieve this by
|
||||
making sure that all allocated objects are passed to `boot` function (so that it
|
||||
does not do any allocations internally). Call these new functions `boot!` and
|
||||
`simbootT2`. You might need to use the `Threads.threadid` and `Threads.nthreads`
|
||||
functions.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -195,8 +168,21 @@ Indeed, we see that the number of allocations was decreased, which should lower
|
||||
GC usage. However, the runtime of the simulation is similar since in this task
|
||||
memory allocation does not account for a significant portion of the runtime.
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 5
|
||||
|
||||
Use either of the solutions we have developed in the previous exercises to
|
||||
create a web service taking `k` and `n` parameters and returning the values
|
||||
produced by `boot` functions and time to run the simulation. You might want to
|
||||
use the `@timed` macro in your solution.
|
||||
|
||||
Start the server.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution (I used the simplest single-threaded code here; this is a complete
|
||||
code of the web service):
|
||||
|
||||
@ -238,8 +224,19 @@ end
|
||||
Genie.Server.up()
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 6
|
||||
|
||||
Query the server started in the exercise 5 with
|
||||
the following parameters:
|
||||
* `k=1000` and `n=1000`
|
||||
* `k=1.5` and `n=1000`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -274,8 +271,17 @@ Transfer-Encoding: chunked
|
||||
|
||||
As expected we got a positive answer the first time and an error on the second call.
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 7
|
||||
|
||||
Collect the data generated by a web service into the `df` data frame for
|
||||
`k = [10^i for i in 3:6]` and `n = [10^i for i in 1:3]`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -316,8 +322,16 @@ julia> df
|
||||
12 │ OK 7.23958 {\n "k": 1000000,\n "n…
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 8
|
||||
|
||||
Replace the `value` column in the `df` data frame by its contents in-place.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -340,8 +354,17 @@ julia> select!(df, :status, :time, :value => AsTable)
|
||||
12 │ OK 7.23958 1000000 1000 0.63232 0.632301 0.63234
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 9
|
||||
|
||||
Checks that execution time roughly scales proportionally to the product
|
||||
of `k` times `n`.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
|
||||
```
|
||||
@ -366,8 +389,17 @@ single sample stabilizes (for small values the runtime is low so the timing is
|
||||
more affected by external noise and the other operations that the functions do
|
||||
affect the results more).
|
||||
|
||||
</details>
|
||||
|
||||
### Exercise 10
|
||||
|
||||
Plot the expected fraction of seen elements in the set as a function of
|
||||
`n` by `k` along with 95% confidence interval around these values.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Solution</summary>
|
||||
|
||||
Solution:
|
||||
```
|
||||
using Plots
|
||||
|
Loading…
Reference in New Issue
Block a user