Det her er ret imponerende.
Der er nogle firmaer der har fået nogle gevaldige performance forbedringer ved at bruge Go (ikke Go!) programmeringssproget: http://golang.org
De gik fra at bruge 30 servere med Ruby på der havde en tendens til kollosalt clusterf**k til 2 servere der kører uden problemer (og den ene af de 2 servere er der endda kun på grund af redundanskrav).
http://blog.iron.io/2013/03/how-we-went-from-30-servers-to-2-go.html
http://blog.iron.io/2013/08/go-after-2-years-in-production.html
For det program som iron.io kører, så bruger Go betydeligt mindre RAM (ca 500 KB vs 50 MB) ved opstart, og under drift bruger den kun 5% CPU saft - i forhold til at det før var 50% CPU saft.
Der er mange der bruger Go - blandt de første på den her liste finder du Canonical, der bruger Go på deres servere
http://go-lang.cat-v.org/organizations-using-go
Go er et sprog der oversætter til maskinkode meget hurtigt. Go compileren leverer programmet som en alt-i-en-fil program, så der er absolut ingen afhængigheder.
Go er rigtig god til at køre noget i parallel a la Erlang programmeringssproget.
Det kan multiplekse 10.000er af go rutiner (svarer til Java green threads fra dengang Java 1.4 var helt nyt) ned til nogle få kernel threads.
Pt har jeg droppet Python og bruger nu Go, fordi det er sjovere at kode i Go.
---
Jeg har en ide om at prøve at lave en webapplikation i Go.
Jeg har en ide der på masknen hvor administrationen skal foregå startes en webapplikation (manuelt eller per automatik).
Med en browser, samt et server certifikat+et klient certifikat (evt begge hjemmelavet) kobler administrator sig så op - man bestemmer naturligvis selv)
Webapplikationen startes op på en Linux server/desktop, og kan så på en helt anden desktop (eller samme desktop, hvis den kører webapplikationen), eller en tablet, så få en grafisk brugergrænseflade til at administrere for eksempel pakker på Linux serveren/desktop maskinen.
Det er en slags web udgave af softwarecenteret om man vil. Ideen er at en administrator kan logge ind og nemt installere og fjerne pakker, f.eks. mens han har en bruger i telefon røret.
---
Er du selv blevet interesseret kan du tage Tour'en på http://golang.org - den er på 84 trin, så vidt jeg lige husker, og man kommer rundt om det meste.
/Lars
Programmeringssprog - Ruby vs Go: Fra 30 til 2 servere
-
- Indlæg: 5095
- Tilmeldt: 27. apr 2008, 02:16
- IRC nickname: lars_t_h
- Geografisk sted: Fyn
Programmeringssprog - Ruby vs Go: Fra 30 til 2 servere
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
-
- Indlæg: 5095
- Tilmeldt: 27. apr 2008, 02:16
- IRC nickname: lars_t_h
- Geografisk sted: Fyn
Kvadratrodsberegning med Newtons metode
Her er en stump Go kode der er implementering af en beregning af kvadratrod ved at bruge Newtons metode:
Kildekode
Lad os antage at du gemmer koden i filen sqrt_newton.go
Før du går igang så skal du sætte en bunke miljø variabler:
Bemærk at kommandoerne antager at din Go mappe er ~/bin/go mappe.
Bruger du en anden mappe så omskriv 1. linie:
ADVARSEL: Bemærk at du ikke må lave ged i linien med PATH, ellers kan Ubuntu ikke finde dine programmer.
Du kan så vælge at pretty printe (få kildekoden til at se pæn ud, når du læser) den med den her kommando fra samme mappe som filen er i:
Nu kan du med Go compileren installeret oversættes kildekoden - og det er stadig imens Bash fortolkeren (terminalen) er placeret i samme mappe som kildekoden filen (sqrt_newton.go) er i
Ud kommer en ny fil der er et kørbart program med uoptimeret maskinkode, hvilket er årsag til at den fylder 1,5 MB.
Kommandoen giver:
Du kan nu køre filen med
Den skriver:
Som du kan se så beregner den faktisk kvadratroden af 2.
Det er Sqrt(a) i func Main, der kalder vores funktion func Sqrt, i func Main kan du også se at det første jeg gør er at oprette en variabel a, der tildeles værdien 2:
(et '.'(=punktum) får 2 til at blive til et decimaltal i stedet for et heltal)
Allerede ved det 5 gennemløb har den fat i det helt rigtige tal.
Havde jeg lavet algoritmen lidt smartere, så holder den op med at gentage beregningen i for løkken, når forrige z værdi er meget lidt forskellig fra den nye beregning af z.
Til sammenligning er det sidste programmet gør (det sidste den udskriver) er at bruge math.Sqrt, dvs bruge den indbyggede kvadratrodsalgoritme fra standardbiblioteket.
---
Programmet har ingen afhængigheder.
Afhængigheder kan man se med ldd komandoen.
som skriver:
file komandoen viser det også, bare på en anden måde.
som giver
Her er det staticallly linked der fortæller dig at der ikke er nogen afhængigheder.
Håber det er sjovt for nogen at læse lidt om hvordan man laver kildekode og så oversætter det.
/Lars
Kildekode
Kode: Vælg alt
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) (z float64) {
var nævner, tæller float64
z = x
for i := 1;i <= 10; i++ {
nævner = (z * z) - x
tæller = 2 * z
z = z - (nævner / tæller)
fmt.Println("i=",i,",z=", z)
}
return
}
func main() {
var a = 2.
fmt.Println(Sqrt(a))
fmt.Println(math.Sqrt(a))
}
Lad os antage at du gemmer koden i filen sqrt_newton.go
Før du går igang så skal du sætte en bunke miljø variabler:
Kode: Vælg alt
export GOBASEDIR=$HOME/bin/go
export GOROOT=$GOBASEDIR
export GOPATH=$GOBASEDIR/bin
PATH=$PATH:$GOBASEDIR/bin
Bemærk at kommandoerne antager at din Go mappe er ~/bin/go mappe.
Bruger du en anden mappe så omskriv 1. linie:
- start med at skrive export GOBASEDIR=
- uden mellemrumstegn eller noget andet, så tilføj den absolutte sti til mappen
- Den absolutte sti til mappen må ikke indeholde mellemrumstegn.
- Du må ikke afslutte med et /-tegn.
ADVARSEL: Bemærk at du ikke må lave ged i linien med PATH, ellers kan Ubuntu ikke finde dine programmer.
Du kan så vælge at pretty printe (få kildekoden til at se pæn ud, når du læser) den med den her kommando fra samme mappe som filen er i:
Kode: Vælg alt
go fmt sqrt_newton.go
Nu kan du med Go compileren installeret oversættes kildekoden - og det er stadig imens Bash fortolkeren (terminalen) er placeret i samme mappe som kildekoden filen (sqrt_newton.go) er i
Kode: Vælg alt
go build sqrt_newton.go
Ud kommer en ny fil der er et kørbart program med uoptimeret maskinkode, hvilket er årsag til at den fylder 1,5 MB.
Kommandoen
Kode: Vælg alt
ls -lh
totalt 1,5M
-r-xr-xr-x 1 lars lars 1,5M aug 26 04:10 sqrt_newton
-r--r--r-- 1 lars lars 384 aug 26 04:03 sqrt_newton.go
Du kan nu køre filen med
Kode: Vælg alt
./sqrt_newton
Den skriver:
i= 1 ,z= 1.5
i= 2 ,z= 1.4166666666666667
i= 3 ,z= 1.4142156862745099
i= 4 ,z= 1.4142135623746899
i= 5 ,z= 1.4142135623730951
i= 6 ,z= 1.414213562373095
i= 7 ,z= 1.4142135623730951
i= 8 ,z= 1.414213562373095
i= 9 ,z= 1.4142135623730951
i= 10 ,z= 1.414213562373095
1.414213562373095
1.4142135623730951
Som du kan se så beregner den faktisk kvadratroden af 2.
Det er Sqrt(a) i func Main, der kalder vores funktion func Sqrt, i func Main kan du også se at det første jeg gør er at oprette en variabel a, der tildeles værdien 2:
Kode: Vælg alt
var a = 2.
(et '.'(=punktum) får 2 til at blive til et decimaltal i stedet for et heltal)
Allerede ved det 5 gennemløb har den fat i det helt rigtige tal.
Havde jeg lavet algoritmen lidt smartere, så holder den op med at gentage beregningen i for løkken, når forrige z værdi er meget lidt forskellig fra den nye beregning af z.
Til sammenligning er det sidste programmet gør (det sidste den udskriver) er at bruge math.Sqrt, dvs bruge den indbyggede kvadratrodsalgoritme fra standardbiblioteket.
---
Programmet har ingen afhængigheder.
Afhængigheder kan man se med ldd komandoen.
Kode: Vælg alt
ldd sqrt_newton
ikke et dynamisk kørbart programr
file komandoen viser det også, bare på en anden måde.
Kode: Vælg alt
file sqrt_newton
sqrt_newton: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
Her er det staticallly linked der fortæller dig at der ikke er nogen afhængigheder.
Håber det er sjovt for nogen at læse lidt om hvordan man laver kildekode og så oversætter det.
/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
-
- Indlæg: 5095
- Tilmeldt: 27. apr 2008, 02:16
- IRC nickname: lars_t_h
- Geografisk sted: Fyn
Re: Programmeringssprog - Ruby vs Go: Fra 30 til 2 servere
Jeg fandt lige ud af at der findes noget der både er en online pastebin for Go kildekode og også en online Go compiler (som dog er begrænset så den ikke kan misbruges):
Den findes på http://play.golang.org
Et konkret eksempel er naturligvis kildekoden i mit indlæg ovenover det her indlæg
Gå ind på den her web side: http://play.golang.org/p/lPmVFlOV9h - og tryk på Run knappen på web siden, så vil Go kilekoden blive oversat og kørt af en Go compiler.
Resultatet vises under kildekoden.
/Lars
Den findes på http://play.golang.org
Et konkret eksempel er naturligvis kildekoden i mit indlæg ovenover det her indlæg
Gå ind på den her web side: http://play.golang.org/p/lPmVFlOV9h - og tryk på Run knappen på web siden, så vil Go kilekoden blive oversat og kørt af en Go compiler.
Resultatet vises under kildekoden.
/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags
-
- Indlæg: 5095
- Tilmeldt: 27. apr 2008, 02:16
- IRC nickname: lars_t_h
- Geografisk sted: Fyn
Re: Programmeringssprog - Ruby vs Go: Fra 30 til 2 servere
Her er iøvrigt den forbedrede udgave der stopper når forskellen er lille nok, eller for-løkken blev kørt for mange(=i_max) gange.
http://play.golang.org/p/E-8mnu3Med
Igen - tryk på Run knappen
Prøv at smide en masse ekstra nuller ind imellem . og 1 i linien:
tryk på Run og se hvad der sker. Hvis compileren brokker sig, så forsøg dig med færre nuller indtil den ikke længere brokker sig.
Hvis den ikke kører 50 gange så tilføj flere nuller.
Laver du forsøgene herunder, så skal du have masser af ekstra nuller i diff variablen
Hvis den kører 50 gange så prøv at ændre
... så tallet bliver et større positivt heltal og kør med Run. Prøv også med et mindre positivt heltal.
Hvad sker der, hvis du gør tallet negativt?
Altså: Lav i_max til at blive -50.
Kun 1 gennemløb igennem løkken, hvis i_max er et negativt tal?
Det er fordi at vores test:
i linien
... aldeles omgående giver et falsk udsagn, som er det der stopper løkken.
Stadig imens du har mange ekstra nuller i diff og i_max og et negativt tal, så prøv at foretage de her ændringer:
Ændre denne linie fra det her:
til det her:
og
ændre på i_max variablen. Det er linien som begynder med
Skal du ændre den så den begynder med:
Bemærk at der efter '=' tegnet i vores program skal stå et tal.
Hvis du slettede tallet, så bliver compileren sur, og nægter at lave et program til dig. (prøv det).
Nu er sqrtExitLoopI funktionen fikset, så compileren er glad, men vi skal lige rette i Sqrt funktionen:
Ændr
så der står
Nu er compileren glad, hvad angår 'i' variablerne i Sqrt, og sqrtExitLoopI funktionerne og også i_max variablen, men compileren er ikke helt glad lige nu, fordi du bruger et negativt tal ved i_max variablen.
Du får den her besked:
Det kan oversættes til at der i en i en uint32 type ikke kan være et negativt tal, for det er hvad u'et i uint betyder.
U'et er fra ordet unsigned, der betyder at den mest betydende bit(MSb) ikke er reserveret til at angive om at tallet er negativt (logisk 1), eller enten positivt eller nul (logisk 0).
Prøv at ændre i_max til et passende stort positivt heltal, f.eks. 100.000 og kør igen med Run.
Du får den her besked:
... og det er en af begræningerne på play.golang.org du er løbet ind, nemlig at Go programmerne kun kan køre i meget kort tid. - Ingen gratis Google App Engine hosting her.
Installerer du derimod Go compileren og har kildekoden i proc.go, så vil den her 3-i-1 kommando både oversætte kildekoden til maskinkode, lave dig et Linux program (linke det) og køre programmet:
Kommandoen virker kun, hvis terminalen er i samme mappe som 'proc.go'.
Får du compiler fejl bliver programmet './proc' ikke lavet og du får en 'fil ikke fundet' fejl fra terminalen.
Du kan kan afbryde et terminalprogram med tastekombination CTRL+C - det er den der normalt er kopier til udklipsholderen i GUI programmer og desktoppen. I terminalen har den bare en anden betydning.
/Lars
http://play.golang.org/p/E-8mnu3Med
Igen - tryk på Run knappen
Prøv at smide en masse ekstra nuller ind imellem . og 1 i linien:
Kode: Vælg alt
const diff float64 = 0.000000001
tryk på Run og se hvad der sker. Hvis compileren brokker sig, så forsøg dig med færre nuller indtil den ikke længere brokker sig.
Hvis den ikke kører 50 gange så tilføj flere nuller.
Laver du forsøgene herunder, så skal du have masser af ekstra nuller i diff variablen
Hvis den kører 50 gange så prøv at ændre
Kode: Vælg alt
const i_max int32 = 50
... så tallet bliver et større positivt heltal og kør med Run. Prøv også med et mindre positivt heltal.
Hvad sker der, hvis du gør tallet negativt?
Altså: Lav i_max til at blive -50.
Kun 1 gennemløb igennem løkken, hvis i_max er et negativt tal?
Det er fordi at vores test:
Kode: Vælg alt
i >= i_max
i linien
Kode: Vælg alt
if i >= i_max {
... aldeles omgående giver et falsk udsagn, som er det der stopper løkken.
Stadig imens du har mange ekstra nuller i diff og i_max og et negativt tal, så prøv at foretage de her ændringer:
Ændre denne linie fra det her:
func sqrtExitLoopI(i int32, do_loop *bool) {
til det her:
Kode: Vælg alt
func sqrtExitLoopI(i uint32, do_loop *bool) {
og
ændre på i_max variablen. Det er linien som begynder med
const i_max int32 =
Skal du ændre den så den begynder med:
Kode: Vælg alt
const i_max uint32 =
Bemærk at der efter '=' tegnet i vores program skal stå et tal.
Hvis du slettede tallet, så bliver compileren sur, og nægter at lave et program til dig. (prøv det).
Nu er sqrtExitLoopI funktionen fikset, så compileren er glad, men vi skal lige rette i Sqrt funktionen:
Ændr
var i int32 = 1
så der står
Kode: Vælg alt
var i uint32 = 1
Nu er compileren glad, hvad angår 'i' variablerne i Sqrt, og sqrtExitLoopI funktionerne og også i_max variablen, men compileren er ikke helt glad lige nu, fordi du bruger et negativt tal ved i_max variablen.
Du får den her besked:
prog.go:24: constant -50 overflows uint32
[process exited with non-zero status]
Program exited.
Det kan oversættes til at der i en i en uint32 type ikke kan være et negativt tal, for det er hvad u'et i uint betyder.
U'et er fra ordet unsigned, der betyder at den mest betydende bit(MSb) ikke er reserveret til at angive om at tallet er negativt (logisk 1), eller enten positivt eller nul (logisk 0).
Prøv at ændre i_max til et passende stort positivt heltal, f.eks. 100.000 og kør igen med Run.
Du får den her besked:
Error communicating with remote server.
Program exited.
... og det er en af begræningerne på play.golang.org du er løbet ind, nemlig at Go programmerne kun kan køre i meget kort tid. - Ingen gratis Google App Engine hosting her.
Installerer du derimod Go compileren og har kildekoden i proc.go, så vil den her 3-i-1 kommando både oversætte kildekoden til maskinkode, lave dig et Linux program (linke det) og køre programmet:
Kode: Vælg alt
rm -f ./proc.go;go build proc.go;./proc
Kommandoen virker kun, hvis terminalen er i samme mappe som 'proc.go'.
Får du compiler fejl bliver programmet './proc' ikke lavet og du får en 'fil ikke fundet' fejl fra terminalen.
Du kan kan afbryde et terminalprogram med tastekombination CTRL+C - det er den der normalt er kopier til udklipsholderen i GUI programmer og desktoppen. I terminalen har den bare en anden betydning.
/Lars
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags