Skip to content

Commit 99178b1

Browse files
author
Henrik Kirk
committed
Moved lectures to fit BS
1 parent 689d1fc commit 99178b1

File tree

10 files changed

+214
-216
lines changed

10 files changed

+214
-216
lines changed

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ <h3>Web (Giraffe)</h3>
6565

6666
<section>
6767
<h1>Lecture 10</h1>
68-
<h3></h3>
68+
<h3>Efficiency</h3>
6969
<div>Can be found <a href="./slides/10/">here</a></div>
7070
</section>
7171
<section>

slides/105/efficiency.md renamed to slides/10/efficiency.md

Lines changed: 0 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -389,221 +389,6 @@ let foldBack f m x =
389389
```
390390

391391

392-
393-
----
394-
395-
### Performance
396-
397-
```fsharp
398-
type A = {X: int; Y: int}
399-
// vs
400-
[<Struct>]
401-
type B = {X: int; Y: int}
402-
```
403-
404-
* Type `B` is 16 bytes smaller, not having `8B` Object header + `8B` vTabel
405-
* `B` is passed as values, therefore not always faster
406-
407-
----
408-
409-
### Padding
410-
411-
```fsharp
412-
type A = {X: int; Y: int}
413-
type B = {X: int; Y: int; Y: int}
414-
```
415-
416-
* Here `B` is padded with 4 bytes extra, from the .NET Allocator
417-
418-
419-
----
420-
421-
### Union types
422-
423-
![Discriminated unions](./img/class-vs-struct-union-1.png)
424-
425-
426-
----
427-
428-
### Immutable data structures
429-
430-
Records, unions, Lists etc etc.
431-
432-
* Fewer movings parts
433-
* Thread-safe by default
434-
* % Not nessesary performance optimal.
435-
* Change to use mutable datastructures within a module/function to gain performance.
436-
437-
----
438-
439-
### Other things to consider
440-
441-
* Hardware, L1, L2, caches
442-
* OS pointer sizes 32/64b
443-
* Inlining functions
444-
445-
F# can be very [performant](https://www.youtube.com/@FastFSharp) - used by stock companies because of this and its safety. But it requires work and knowledge about .Net Il, Hardware and F# of course.
446-
447-
---
448-
449-
### Amortized bounds
450-
451-
* An extension to the Big-O notation from DOA
452-
* Used to analysis average run time
453-
* Usually used when some operations are fast and other are slow
454-
455-
* C# List is an example, its worst case bounds
456-
* insert: `$ O(n) $` -- **why?**
457-
* lookup: `$ O(1) $`
458-
* delete: `$ O(1) $`
459-
460-
----
461-
462-
### C# List analysis over time
463-
464-
* `$ \rightarrow $` `n` insertions are `$ O(n^2) $` worst case
465-
* You can make the amortized analysis that shows <!-- .element: class="fragment" data-fragment-index="1" -->
466-
* `n` insertions are `$ O(2n) $` <!-- .element: class="fragment" data-fragment-index="1" -->
467-
* So amortized bounds are `$ O(1) $` for all operations <!-- .element: class="fragment" data-fragment-index="1" -->
468-
* See references for detailed analysis<!-- .element: class="fragment" data-fragment-index="1" -->
469-
470-
471-
---
472-
473-
## Queue
474-
475-
![Queue](./img/queue.jpg "Queue") <!-- .element style="width:800px;" -->
476-
477-
----
478-
479-
### Definition and operation
480-
481-
```fsharp [5-10]
482-
module Queue
483-
484-
type Queue<'a> = 'a list * 'a list
485-
486-
val empty: Queue<'a>
487-
val isEmpty: Queue<'a> -> bool
488-
489-
val cons: 'a -> Queue<'a> -> Queue<'a>
490-
val head: Queue<'a> -> 'a
491-
val tail: Queue<'a> -> Queue<'a>
492-
```
493-
494-
* Could be done with a single list <!-- .element: class="fragment" -->
495-
496-
----
497-
498-
### Operation implementations
499-
500-
```fsharp [2,7|3,8|4,9]
501-
let rec head = function
502-
| ([], []) -> raise (ArgumentException "Empty")
503-
| ([], r) -> head (List.rev r, [])
504-
| (l, _) -> List.head l
505-
506-
let rec tail = function
507-
| ([], []) -> raise (ArgumentException "Empty")
508-
| ([], r) -> tail (List.rev r, [])
509-
| (l, r) -> (List.tail l, r)
510-
```
511-
512-
----
513-
514-
515-
### Using lazy evaluation
516-
517-
* To optimize our queue [https://en.wikipedia.org/wiki/Chris_Okasaki](C. Okasaki) proposes to use lazy lists.
518-
* Almost like `seq`` in F#
519-
520-
```fsharp
521-
module LazyQueue
522-
523-
type LazyQueue<'a> = seq<'a> * seq<'a>
524-
525-
val empty: LazyQueue<'a>
526-
val isEmpty: LazyQueue<'a> -> bool
527-
528-
val cons: 'a -> LazyQueue<'a> -> LazyQueue<'a>
529-
val head: LazyQueue<'a> -> 'a
530-
val tail: LazyQueue<'a> -> LazyQueue<'a>
531-
```
532-
<!-- .element: class="fragment" -->
533-
534-
----
535-
536-
### Lazy queue impl (1/2)
537-
538-
So here we utilises that `Seq` is lazy
539-
540-
```fsharp
541-
let l' = Seq.append l r
542-
```
543-
544-
This do not evalute `r` before its needed
545-
546-
----
547-
548-
### Lazy queue impl (2/2)
549-
550-
```fsharp
551-
let l` = Seq.append l (Seq.rev r)
552-
```
553-
554-
1. since append is lazy, we need to do `Seq.rev` incrementally.
555-
2. so do one step of `Seq.rev` for each step of append
556-
3. we then need the invariant `Seq.length r <= Seq.length l`
557-
558-
Note:
559-
Seq.rev - will reverse the list in one go
560-
561-
```fsharp
562-
// https://github.com/fsharp/fsharp/blob/577d06b9ec7192a6adafefd09ade0ed10b13897d/src/fsharp/FSharp.Core/seq.fs#L1424
563-
let rev source =
564-
checkNonNull "source" source
565-
mkDelayedSeq (fun () ->
566-
let array = source |> toArray
567-
Array.Reverse array
568-
array :> seq<_>)
569-
```
570-
571-
----
572-
573-
### Incremental rotation
574-
575-
```fsharp
576-
let rec rot (l, r, a) = match Seq.length l
577-
| 0 -> (Seq.head r) :: a
578-
| 1 -> (Seq.head l) :: (rot
579-
(Seq.tail l, Seq.tail r, Seq.head r :: a))
580-
```
581-
582-
\* Not battle tested code
583-
584-
\*\* Not optimized code
585-
586-
----
587-
588-
### Bounds
589-
590-
* Amortized bounds for all operations are still `$ O(1) $`
591-
* Worst case `$ O(log n) $`
592-
593-
----
594-
595-
### Amortization
596-
597-
* Not useful in `realtime` systems
598-
* why?
599-
600-
----
601-
602-
### Deque idea
603-
604-
![Deque](./img/deque.png "Deque")
605-
606-
607392
---
608393

609394
## References
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)