From 16e543163bbfc40d6360cded8437160bbd994000 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Thu, 25 Mar 2010 16:15:52 +1100 Subject: [PATCH] Sydney University tech talk. R=adg CC=golang-dev https://golang.org/cl/744042 --- doc/talks/go_talk-20100323.html | 395 ++++++++++++++++++++++++++++++++ doc/talks/java-typing.png | Bin 0 -> 19328 bytes 2 files changed, 395 insertions(+) create mode 100644 doc/talks/go_talk-20100323.html create mode 100644 doc/talks/java-typing.png diff --git a/doc/talks/go_talk-20100323.html b/doc/talks/go_talk-20100323.html new file mode 100644 index 0000000000..3143b079ae --- /dev/null +++ b/doc/talks/go_talk-20100323.html @@ -0,0 +1,395 @@ + + + +Go Tech Talk + + + + + + + + +
+ +
+ +
+ + +
+ +
+
+
+ +
+

The Go Programming Language

+
+
+

Sydney University

March 23, 2010

+
+
+ +
+

Go

+ +

New

+

Experimental

+

Concurrent

+

Garbage Collected

+

Systems Language

+
+ +
+

Hello, world

+
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Printf("Hello, 世界\n")
+}
+
+
+ +
+

Hello, world 2.0

+ +

Serving http://localhost:8080/world

+
+package main
+
+import (
+	"fmt"
+	"http"
+)
+
+func handler(c *http.Conn, r *http.Request) { 
+	fmt.Fprintf(c, "Hello, %s.", r.URL.Path[1:]) 
+}
+
+func main() {
+	http.ListenAndServe(":8080",
+			http.HandlerFunc(handler))
+}
+
+
+ +
+

New

+ +

It's about two years old:

+ + +

Why invent a new language? Older languages weren't designed for concurrency, but modern software needs it:

+ +
+ +
+

New

+ +

Older languages are also frustrating on a day-to-day basis

+

Statically-typed languages (C, C++, Java) have issues:

+ +
+
+
+ +

Dynamic languages (Python, JavaScript) fix some issues but introduce others:

+ + +

Go has the lighter feel of a scripting language but is compiled

+
+ +
+

New

+ +

Large C++ programs (e.g. Firefox, OpenOffice, Chromium) have enormous build times:

+ + +

On a Mac (OS X 10.5.8, gcc 4.0.1):

+ + +

In Go: import "fmt" reads one file: 184 lines summarizing 7 packages

+
+ +
+

New

+ +

Compilation demo

+
+ +
+

Experimental

+ +

Go is still unproven

+

Language is still evolving

+

Package library is incomplete

+

Concurrent garbage collection is an active research problem

+

Reviving forgotten concepts:

+ +
+ +
+

Concurrent

+ +

Unix philosophy: write programs that do one thing and do it well

+

Connect them with pipes:

+ + +

Unlike other languages, Go makes it easy to:

+ +
+ +
+

Concurrent

+ +

Start a new flow of control with the go keyword

+

Parallel computation is easy:

+
+func main() {
+	go expensiveComputation(x, y, z)
+	anotherExpensiveComputation(a, b, c)
+}
+
+ +

Roughly speaking, a goroutine is like a thread, but lighter weight:

+ +
+ +
+

Concurrent

+ +

Consider web servers ("the C10k problem"):

+ +
+	for {
+		rw := socket.Accept()
+		conn := newConn(rw, handler)
+		go conn.serve()
+	}
+
+
+ +
+

Concurrent

+ +

Let's look again at our simple parallel computation:

+
+func main() {
+	go expensiveComputation(x, y, z)
+	anotherExpensiveComputation(a, b, c)
+}
+
+ +

This story is incomplete:

+ +
+ +
+

Concurrent

+ +

Goroutines communicate with other goroutines via channels

+
+func computeAndSend(ch chan int, x, y, z int) {
+	ch <- expensiveComputation(x, y, z)
+}
+
+func main() {
+	ch := make(chan int)
+	go computeAndSend(ch, x, y, z)
+	v2 := anotherExpensiveComputation(a, b, c)
+	v1 := <-ch
+	fmt.Println(v1, v2)
+}
+
+ +
+ +
+

Concurrent

+ +

In traditional concurrent programs, you communicate by sharing memory. In Go, you share memory by communicating:

+ + +

Threads and locks are concurrency primitives; CSP is a concurrency model:

+ + +

Learning CSP changes the way you think about concurrent programming:

+ +
+ +
+

Garbage Collected

+ +

Automatic memory management makes writing (and maintaining) programs easier

+

Especially in a concurrent world:

+ + +

Large C++ programs usually end up with semi-automatic memory management anyway, via "smart pointers"

+

Mixing the two models can be problematic:

+ +
+ +
+

Garbage Collected

+ +

Go is also a safer language:

+ + +

No buffer overflow exploits

+
+ +
+

Systems Language

+ +

This just means you could write decently large programs in Go:

+ +
+ +
+

Systems Language

+ +

Garbage collection has a reputation for being "slower"

+

We're expecting Go to be slightly slower than optimized C, but faster than Java, depending on the task. Nonetheless:

+ + +

Memory layout can drastically affect performance. These two designs are equivalent in Go, but significantly different in Java:

+
+type Point struct { X, Y int }
+type Rect struct { P0, P1 Point }
+
+// or ...
+
+type Rect struct { X0, Y0, X1, Y1 int }
+
+
+ +
+

Systems Language

+ +

Quote from http://loadcode.blogspot.com/2009/12/go-vs-java.html

+ +

+"[Git] is known to be very fast. It is written in C. A Java version +JGit was made. It was considerably slower. Handling of memory and lack +of unsigned types was some of the important reasons. +

+ +

Shawn O. Pearce wrote on the git mailinglist:

+ + +

+Like C, Go does allow unsigned types and defining data structures +containing other data structures as continuous blocks of memory." +

+
+ +
+

Go

+ +

New

+

Experimental

+

Concurrent

+

Garbage Collected

+

Systems Language

+ +

And more:

+ +
+ +
+

Questions?

+

+
+ +
+
+ + diff --git a/doc/talks/java-typing.png b/doc/talks/java-typing.png new file mode 100644 index 0000000000000000000000000000000000000000..54abf0186462138efd900da13f66068a89e4ddf5 GIT binary patch literal 19328 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