Go vs. Rust: porovnání dvou progresivních kompilovaných jazyků

Presentations

Go vs. Rust: porovnání dvou progresivních kompilovaných jazyků

Obsah přednášky (1)

Proč vlastně porovnávat Rust a Go?

Proč vlastně porovnávat Rust a Go?

Ale jedná se SKUTEČNĚ o konkurenty?

Charakteristické rysy Rustu

Charakteristické rysy Rustu (2)

Charakteristické rysy Rustu (3)

fn main() {
    println!("Hello world!");
}
public class Test {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

Rust a C/C++

Správce balíčků (Cargo)

Charakteristické rysy jazyka Go

„Less is more“

Charakteristické rysy jazyka Go

Charakteristické rysy jazyka Go (2)

× Poučení z chyb, které najdeme například v C/C++ - Silný typový systém - Nepoužívají se makra založená na textové substituci - Nepoužívají se hlavičkové soubory - Bezpečná práce s pamětí (+ GC) - Standardizovaný framework pro testování - Rychlé překlady - Syntaktické věci: ++/– jen postfixové a nejsou to výrazy - Nepoužívá se ukazatelová aritmetika - Nepoužívají se šablony - Nejsou podporovány výjimky (prozatím)

Charakteristické rysy jazyka Go (3)

Makra v Go?

Look and feel Go

func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        return
    }
    defer src.Close()

    dst, err := os.Create(dstName)
    if err != nil {
        return
    }
    defer dst.Close()

    return io.Copy(dst, src)
}

Poznámky

Klíčové slovo defer

Zpracování chybových stavů

type error interface {
    Error() string
}

func div(x, y int32) (int32, error) {
        if y == 0 {
                return -1, errors.New("takto ne!")
        }
        return x / y, nil
}

func main() {
        res, err := div(10, 3)
        fmt.Println(res, err)
        res, err = div(10, 0)
        fmt.Println(res, err)
}

Gorutiny

func f(from string) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }
}

func main() {
    f("direct")
    go f("goroutine")
    go func(msg string) {
        fmt.Println(msg)
    }("going")

    fmt.Scanln()
    fmt.Println("done")
}

func main() {
    messages := make(chan string)
    go func() { messages <- "ping" }()
    msg := <-messages
    fmt.Println(msg)
}

Jednoduchá synchronizace v Go

func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")

    // ok uz jsme hotovi, posleme zpravu kanalem
    done <- true
}

func main() {
    // kanal s kapacitou == 1
    done := make(chan bool, 1)

    // asynchronni beh
    go worker(done)

    // cekame na zpravu
    <-done
}

A samozřejmě oblíbené téma pro debaty…

Vybrané společné rysy jazyků Go a Rust

Vlákna

Správa chyb

Porovnání Rustu a Go

Porovnání Rustu a Go - komunita, akceptace

Jazyk            Rust           Go
Adaptace         pomalejší      rychlejší
Tiobe index      #31 (0,396%)   #16 (1,081%)
Stackshare       313            2780
Stack overflow   10100          32700
GitHub           30900 *        47500 *
GitHub           5210 forků     6510 forků
SO survey        79%            66% (loved)
SO survey         8%            16% (wanted)
(most dreaded Visual Basic 6 89.9% :-)

Porovnání Rustu a Go z hlediska vývojáře

Jazyk             Rust           Go
Přístup           moderní        konzervativní
Syntaxe           komplikovaná   jednoduchá, minimalistická
Učící křivka      menší sklon    větší sklon
Učící křivka      větší ampli.   menší amplituda
Rychlost překladu pomalejší      rychlejší
Backend           LLVM           vlastní
Linkování         static/dynamic přes -buildmode (//export!!!)
Rychlost kódu     rychlejší      pomalejší
Typový systém     rozsáhlý       bez generik
Neměnnost         explicitní     string, další přes rozhraní
Práce s pamětí    vlastnictví    GC
Detekce souběhu   ano            jen nepřímo
Závislosti        cargo          Go moduly

Poznámka k souběhu

Rychlost přeložených aplikací

Rychlost přeložených aplikací

https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/rust-go.html

regex-redux
source  secs    mem      gz      cpu    cpu load
Rust    2.54    204,160  765     3.95   55% 30% 56% 18%
Go     28.69    407,444  802    60.43   46% 51% 68% 46%

binary-trees
source  secs    mem      gz      cpu    cpu load
Rust    3.98    165,920  721     14.61  90% 100% 90% 89%
Go     28.90    471,068  654    110.50  96% 95% 95% 97%

mandelbrot
source  secs    mem      gz      cpu    cpu load
Rust    1.75    34,176   1332    6.86   98% 98% 100% 98%
Go      5.47    31,280   905     21.73  99% 99% 99% 100%

k-nucleotide
source  secs    mem      gz      cpu    cpu load
Rust    5.34    138,504  1749    17.16  87% 100% 78% 58%
Go     15.36    148,056  1722    54.61  77% 96% 95% 88%

reverse-complement
source  secs    mem      gz      cpu    cpu load
Rust    1.61    995,100  1376    2.72   25% 81% 39% 28%
Go      4.00    824,412   611    4.15   86% 14% 5% 1%

spectral-norm
source  secs    mem      gz      cpu    cpu load
Rust    1.98    2,472    1126    7.86   100% 100% 99% 100%
Go      3.95    2,412     548   15.70   100% 99% 99% 99%

fannkuch-redux
source  secs    mem     gz      cpu     cpu load
Rust    9.60    1,752   1020    37.68   100% 96% 99% 99%
Go     17.82    1,472    900    71.03   100% 100% 100% 100%

n-body
source  secs    mem     gz      cpu     cpu load
Rust   13.31    1,768   1805    13.31   0% 0% 1% 100%
Go     21.00    1,532   1200    21.00   1% 0% 0% 100%

fasta
source  secs    mem     gz      cpu     cpu load
Rust    1.47    2,988   1906    4.97    88% 83% 90% 84%
Go      2.07    3,168   1358    5.87    39% 83% 84% 79%

pidigits
source  secs    mem     gz      cpu     cpu load
Rust    1.74    4,488   1366    1.74    1% 100% 1% 0%
Go      2.04    8,976    603    2.04    1% 0% 100% 0%

Proč Go?

Proč Rust?

Zkouška dospělosti

A co jazyk D?

Zajímavosti

Odkazy