Pokazywanie postów oznaczonych etykietą Go. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą Go. Pokaż wszystkie posty

wtorek, maja 10, 2011

Zmienne Go ;-)

Wczoraj napisałem, że chciałbym by na Google I/O ogłoszono w końcu "zamrożenie" Go.
I mam to życzenie dziś jeszcze bardziej ;-)

W ramach testowania czy można już uploadować dowolne pliki do Google Docs bez konwersji przy użyciu API (nie można, choć dla wielu kont Google Docs API mówi, że można, ale każda próba kończy się błędem ;-)) postanowiłem sprawdzić czy działa uploadowanie z mojego programu w Go.
Z konwersją działało.
To wszedłem na stronę z portem Go dla Windows, i pobrałem najnowszą wersję r57.1.
Spróbowałem skompilować mój programik i już się nie da ;-)

Zmieniła się definicja typu dla http.Header, stąd przypisanie i zajęcie pamięci robiło się tak:
 req.Header = make(map[string]string)
a teraz tak:
 req.Header = make(map[string][]string)
By wam nie umknęła ta subtelna różnica to pogrubiłem [], które doszły do definicji typu (chyba).

Ta zmiana spowodowała, że nagłówków nie ustawia się już tak:
  req.Header["Slug"]="toster.txt"
teraz dla odmiany robi się to tak:
  req.Header.Set("Slug","toster.txt")
Co akurat nie jest zmianą na gorsze.

Zmieniła się też ilość parametrów w metodzie net.Dial, kiedyś były 3, teraz są 2 ;-)

Zmiany naniosłem, skompilowałem drania i znów nic. Leci mi błąd:
panic: runtime error: makeslice: len out of range

W linii, która wygląda tak:
  var buf []byte = make([]byte,r.ContentLength)
i wiele mi to nie mówi ;-)

OK, zorientowałem się po przyjrzeniu się kodowi i temu co tam wpada, że r.ContentLength ma wartość -1, co jest dziwne bo to powinna być długość odpowiedzi od serwera.... oczywiście jeżeli metoda http.Post działa teraz tak jak działała jeszcze w październiku 2010 roku ;-)

Zaprawdę powiadam wam, iż podziwiam ludzi którzy już teraz używają Go do produkcyjnych projektów ;-)
Ja rozumiem, że między Pythonami występują różnice, które powodują, że kod z niższej wersji Pythona może nie pracować w wyższej, ale nowe wersje Pythona nie wychodzą tak często ;-)


Podobne postybeta
Wysyłamy pliki do Google Docs przy pomocy Go :-)
Wrrr.... złe API ;-)
Ha! Ochidna Echidna potrafi updatować pliki :-)
Airly + Python + Oczyszczacz Powietrza = lepsze oddychanie ;-)
Giń konstruktorze! Giń! ;-)

niedziela, stycznia 30, 2011

Go dla Java'owca ;-) odcinek 2 "kontenery dwa ;-)"

Już tu kiedyś pisałem, że mam w Java'ie 2 ulubione interfejsy ;-) Map i List.
Naturalnym więc jest, że chcę ich w Go ;-)

Dziś przyjrzymy się "zastępcom" List z Java'y.

Są to List i Vector z pakietu container/list i container/vector (szczerze nie wiem jaki jest zwyczaj pisania tego w Go, bo same pakiety zwą się list i vector).

Zacznijmy od Vector, bo ma fajne ficzery :-)

 v:=new(vector.StringVector)
v.Push("test1")
v.Push("test2")
v.Push("test3")
v.Do(func(elem string) {
fmt.Printf(elem+"\n")
})


Ten kawałek kodu wkłada najpierw łańcuchy test1, test2 i test3 do wektora, a później je wypisuje przy pomocy metody Do(func(elem string)).
Sumowanie liczb staje się dużo prostsze dzięki tej metodzie ;-)

 iV:=new(vector.IntVector)
iV.Push(1)
iV.Push(2)
iV.Push(3)
sum:=0
iV.Do(func(elem int) {sum+=elem})
fmt.Printf("sum=%d\n",sum)


Jest też sam Vector, w którym można trzymać wszystkie typy obiektów.
Z wektorami można robić różne różności, od kasowania elementów, przez wycinanie elementów, zmienianie rozmiaru kontenera i podobne. Standard.
Sam miałem największe problemy z załapaniem jak się do wektorów coś wkłada i z nich wyjmuje (chociaż to miałem w przypadku list, bo wektorów wtedy jeszcze nie próbowałem ;-))

Sam Vector to odpowiednik Java'owego List (czy jeśli chcemy klasy konkretnej to ArrayList no i oczywiście Vector'a, którego w Java'ie już się nie powinno używać, bo synchronizacja nam jest zwykle niepotrzebna).

Teraz kolej na List w Go.
Jest to lista dwukierunkowa, której najbliższym krewnym w Java'ie jest LinkedList.
Możemy w niej wkładać elementy na koniec przy pomocy metody PushBack, na początek przy pomocy PushFront, oraz "między" istniejące elementy, tak by nasz nowo włożony znajdował się przed znacznikiem (InsertBefore) albo za znacznikiem (InsertAfter). Możemy też oczywiście iterować przy użyciu metod Next() i Prev().

By przejść od początku do końca takiej listy używamy kod (z dokumentacji Go :)):

for e := l.Front(); e != nil; e = e.Next() {
// do something with e.Value
}


By to samo zrobić od tyłu do przodu użyjemy kodu:
for e := l.Back(); e != nil; e = e.Prev() {
// do something with e.Value
}


I to by było na tyle ;-)

Podobne postybeta
Ściana, czyli rozbijam się na onclick ;-)
Go dla Java'owca ;-) odcinek 1 "klasy"
Bookmarklet do robienia CSV z obligacjami i ich oprocentowaniem ;-)
Jak z metody size() w List w Java'ie dostać ujemną liczbę? ;-)
Ile w tym i przyszłym miesiącu z odsetek za obligacje?

niedziela, stycznia 23, 2011

Metoda Newtona w Go ;-)

Pobudzony najnowszym wpisem Jamesa Goslinga o metodzie Newtona napisałem sobie jej implementację w Go ;-)

Oto ona:
package main

import ("fmt";"math";"os")

// Zamiast różniczki używamy ilorazu prawie różnicowego ;-)
// tak, tak jako pierwszy parametr przekazujemy funkcję :-)
func diff(f func(float64) float64, x float64) float64 {
return (f(x+0.0000000001)-f(x))/0.0000000001
}

func calcX(f func(float64) float64,oldX float64) float64 {
return oldX-f(oldX)/diff(f,oldX)
}

func searchNewton(f func(float64) float64) (result float64,err os.Error) {
result=10.0
oldX:=0.0
delta:=0.0000000001
for count:=0; count<100; count++ {
fmt.Printf("%d %f\n",count,result)
oldX=result
result=calcX(f,result)
if math.Fabs(result-oldX)<delta {
fmt.Printf("Found: %f\n",result)
return
}
}
err=os.NewError("cannot find real value of X")
return
}

func main() {
f2:=func(x float64) float64 { return 2*x*x+3*x-7 }
f2=func(x float64) float64 { return math.Sin(x)*70-7 }
if x,e:=searchNewton(f2); e==nil {
fmt.Printf("Result %f for %f\n",f2(x),x)
} else {
fmt.Printf(e.String())
}
}


Podoba mi się zwięzłość kodu. Chociaż nadal nadmiarowe wydają się te cosie z obsługą błędów.
Strasznie podoba mi się możliwość przekazywania funkcji, to bardzo umila pisanie.


Podobne postybeta
Język Go dla Windows :-)
Go wolniejsze od C i JavaScript, i ciut szybsze niż Java ;-) [a jednak od Java'y też wolniejsze]
Go dla Java'owca ;-) odcinek 1 "klasy"
Wysyłamy pliki do Google Docs przy pomocy Go :-)
Goto Go ;-)

sobota, stycznia 22, 2011

IDE dla Go

Bałem się, że jestem skazany na Notatnik, ale okazuje się, że jest tego trochę.

Sam dziś próbowałem wtyczki dla IntelliJ i wtyczki dla Eclipse'a.
Przy pomocy wtyczki dla IntelliJ nie udało mi się niczego uruchomić. Wtyczka dla Eclipse zwana GoClipse działa za to całkiem sprawnie.

Co prawda upiera się ciągle, że aplikacje są 64 bitowe (bo wrzuca je do katalogu windows_amd64, gdy powinna wrzucać do windows_386), ale można już np. bez żadnego wysiłku tworzyć własne pakiety :-)
Sama struktura plików na dysku jest zwariowana, np. w moim projekcie który ma 1 plik main.go w pakiecie main i jeden o nazwie new_file.go w pakiecie toster wygląda to tak:



GoClipse podświetla ładnie kod i dba o składnię i ładnie to wszystko integruje z Eclipse:



Ogólnie się mnie podoba ;-)


Podobne postybeta
Wyważanie otwartych drzwi
Czekam na MotoTab
Słaby, ale wojujący ateizm - czyli "obiektywne" dziennikarstwo ;-)
Programowanie na Chromebooku :-)
Skazany na urlop ;-)

piątek, stycznia 21, 2011

Goto Go ;-)

Od jakiegoś czasu szukam jakiegoś nowego języka do zabawy, a może i do specjalizacji.
Myślałem o C++, Pythonie i Go. I dziś wygrywa Go ;-)

Np. najprostszy "serwer" HTTP w Go (taki, który zwraca zawsze ten sam tekst) wygląda tak:
package main

import (
"fmt"
"http"
)

func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, world!")
fmt.Print(r)
}

func main() {
http.HandleFunc("/", Hello)
http.ListenAndServe(":8080", nil)
}


Czyż to nie jest genialne?
Niby w Pythonie wygląda podobnie, ale to tutaj jakoś do mnie przemawia.

Ciekawe kiedy doczekamy się oficjalnego portu dla Windows (btw. nie jestem pewien, ale gdy pisałem sobie w Go wysyłanie dokumentów do Google Docs to coś mi chyba na Windows nie działało, z najnowszą wersją portu Go dla Windows już działa :-), choć nadal nie ma 64 bitowej wersji), a później zapowiadanych wersji dla Androida i NaCl (Native Client).

Już to tu pisałem, ale Go mi się zaczyna coraz bardziej podobać.

Przy okazji, ten serwerem u góry jest z bardzo ciekawej prezentacji (video, slajdy z prezentacji), w której adwokat czy ewangelista Go pokazuje jak można szybko zbudować skracacz linków w Go... pomija niestety dość ciekawie brzmiący kawałek o RPC, ale sama prezentacja fajna.


Podobne postybeta
Język Go dla Windows :-)
Wysyłamy pliki do Google Docs przy pomocy Go :-)
Go dla Java'owca ;-) odcinek 2 "kontenery dwa ;-)"
Komputery są naprawdę stare ;-)
strictfp sierota po x87 ;-)

poniedziałek, października 18, 2010

Wysyłamy pliki do Google Docs przy pomocy Go :-)

W ramach szukania pomysłów na wpis do bloga, a i nauki Go chciałem napisać sobie uploadowarkę plików do Google Docs przy pomocy Go........
I częściowo mi się to udało ;-)

Częściowo, bo działa tylko pod Linuskem, pod portem dla Windows nie działa.

Błąd na Windows pojawia się w trakcie próby zalogowania się do Google Docs, a dokładniej do Writely bo tak nazywa się serwis związany z Google Docs [bez arkuszy] dostaję błąd "could not find root certificate for chain", a przez to reszta zabawy nie ma sensu :-(

Na Linuksie jednak wszystko działa :-) i cały program wygląda tak:

package main

import ("fmt";"http";"os";"strings";"io";"net";"bufio")

type nopCloser struct {
io.Reader
}

func (nopCloser) Close() os.Error { return nil }

type readClose struct {
io.Reader
io.Closer
}


func main() {
var user string
var password string
if len(os.Args)==3 {
user = os.Args[1]
password = os.Args[2]
} else {
fmt.Println("Sorry, you need to provide your Google Account credentials")
return
}
fmt.Println(password)
fmt.Println(user)

// OK, tutaj zaczyna się logowanie do serwisów Google, tym razem do "writely" czyli składowiska dla dokumentów, prezentacji i obrazków Google Docs

bodyType:="application/x-www-form-urlencoded"
appName:="RMKGOTest"
appVersion:="0.01"
service:="writely"
var loginRequestBody = "accountType=HOSTED_OR_GOOGLE&Email="+user+"&Passwd="+password+"&service="+service+"&source="+appName+"-"+appVersion;
r,err:=http.Post("https://www.google.com/accounts/ClientLogin",bodyType,strings.NewReader(loginRequestBody))
fmt.Println(err)
reader := r.Body
var buf []byte = make([]byte,r.ContentLength)
reader.Read(buf)
fmt.Println(string(buf))
elems:=strings.Split(string(buf),"\n",-1)
fmt.Println(len(elems))

// OK, już jesteśmy zalogowani, teraz musimy pobrać nagłówki autoryzacji

var authHeader string
for i:=range elems {
if strings.Index(elems[i],"Auth=")==0 {
authHeader=strings.Replace(elems[i],"Auth=","GoogleLogin auth=",1)
}
}

// Teraz przygotowujemy się do wysłania naszego "pliku" do Google Docs :-)

// treść pliku
documentBody:="This is only a test\nSend from Go to Google Docs :-)"
// MIME type
bodyType="text/plain"

// Tworzymy requesta

req:=new(http.Request)
req.Method="POST"
req.RawURL="https://docs.google.com/feeds/default/private/full"
req.ProtoMajor = 1
req.ProtoMinor = 1
req.Host="docs.google.com"
req.Close = true
req.Body=nopCloser{strings.NewReader(documentBody)}
req.Header = make(map[string]string)
req.Header["Content-Type"]=bodyType
req.Header["Authorization"]=authHeader
req.Header["Slug"]="toster.txt"
req.Header["GData-Version"]="3.0"
req.ContentLength=int64(len(documentBody))
c,errNet:=net.Dial("tcp","","docs.google.com:80")

fmt.Println(errNet)
fmt.Println(c)

err2:=req.Write(c)
fmt.Println(err2)
reader2 := bufio.NewReader(c)
resp, err3 := http.ReadResponse(reader2, req.Method)
if err3 != nil {
c.Close()
fmt.Println(err3)
return
}

resp.Body = readClose{resp.Body, c}

fmt.Println(resp.Body)
fmt.Println(resp.ContentLength)
cLen:=resp.ContentLength
if cLen==-1 {
cLen = 8192
}
var buf2 []byte = make([]byte,cLen)
reader2.Read(buf2)
fmt.Println(string(buf2))

c.Close()

}


W celu jego uruchomienia kompilujemy go standardem:
8g httpTest2.go
8l httpTest2.8

i uruchamiamy:
./8.out eMail HasłoDoKontaGoogle

Gdzie eMail to adres którego używamy w Google Docs, a HasłoDoKontaGoogle to hasło do konta związanego z tym mailem.
Ta wersja programu wysyła plik do Google Docs przy pomocy HTTP, jeśli chcemy użyć HTTPS, to trzeba w sekcji import zmienić "net" w "crypto/tls", a w linii z net.Dial trzeba zmienić to net.Dial na tls.Dial, do tego trzeba zmienić docs.google.code:80 na docs.google.code:443.
Po skompilowaniu działa :-)

Efektem działania programu jest pojawienie się nowego pliku toster.txt w Google Docs :-)

Wszystko działa także z kontami w Google Apps.

Teraz parę słów krytyki ;-)
Po pierwsze zwracanie wielu wartości z funkcji jest super, ale tylko do czasu. Bo zawsze trzeba pobrać wszystkie wartości, a że Go chce być pomocne i uznaje za błąd istnienie niewykorzystanej zmiennej to trzeba też używać tych zwracanych wartości. Ja oszukałem bo błędy w większości przypadków tylko wypisuję, w rzeczywistości za każdym razem powinienem stosować taki "idiom":
coś, err = cośIo
if err!=nil {
// obsłuż błąd
return
}

Który jest jak najbardziej OK, ale to, że język do tego zmusza to przeszkadzajka. W ogólnym rozrachunku nie jest to może takie złe, bo w kodzie produkcyjnym trzeba się upewniać czy wszystko poszło OK, ale to męczy. Zresztą często w takich sytuacjach stosuje się sterowanie przepływem przy pomocy wyjątków, co nie jest ładne, ale jest szybsze w pisaniu, czyli robi się serie rzeczy, które mogą spowodować wyjątek, i jeśli wyjątek nie poleci to sterowanie przechodzi do następnej linii, aż wystąpi wyjątek, albo wszystko się uda zrobić.

Po drugie, pomieszanie światów. Raz używając http można stworzyć cały request POST i go wysłać, drugim razem trzeba zniżyć się do net albo crypto/tls czyli do poziomu socketów bo zechcieliśmy wykonać jedną nietypową rzecz, czyli ustawić nagłówki requesta.
W tym miejscu może nawet więcej sensu miałoby użycie tylko net albo crytpo/tls bez bawienia się w requesty.

Po trzecie, to wkurzające wymaganie jawnej konwersji typów. Java robi to milej. Przez tą konwersję trzeba ciągle kombinować. Przez co mam taką linię:
req.ContentLength=int64(len(documentBody))
Bo oczywiście do ContentLength trzeba włożyć int64, a len zwraca "tylko" int.
Strasznie to upierdliwe.

Po czwarte, nadużywanie struktur. Jak widać w źródle, musiałem ukraść ze źródeł Go 2 struktury, nopCloser i readClose, bo komuś się ubzdurało, żeby strumień i jego zamykanie były oddzielnymi bytami, ale akurat do wielu bibliotek trzeba dostarczać strumienie, które są jednocześnie czytalne czy zapisywalne i zamykalne......

Po piątek, zmiany w kompilatorze. To jest na razie język eksperymentalny, choć Google podobno pisze w nim niektóre swoje wewnętrzne narzędzia.
Np. to, że teraz nie używa się średnika bo kompilator sam sobie go potrafi włożyć, nie działa z kompilatorem sprzed pół roku czy jakoś tak. Biblioteki też się zmieniają.

Po szóste, port dla Windows. Nie ma oficjalnego, jest taki mniej oficjalny, który ma np. problemy z HTTPSem.

Dla ciekawskich, ten program wyżej to dziecko jakichś 4 godzin, czyli dość długo powstawał.


Podobne postybeta
Zmienne Go ;-)
Chrome OS, Chrome2Chrome i w ogóle Chrome ;-)
Toperz ;-) czyli OCR + Android odsłona 2 albo któraś tam
Go dla Java'owca ;-) odcinek 1 "klasy"
Wredne Google Docs

poniedziałek, października 04, 2010

Go dla Java'owca ;-) odcinek 1 "klasy"

Od kilku dni czytam sobie o Go, głównie rekreacyjnie, ale z tyłu głowy mam to, że może kiedyś będzie trzeba przejść na Go, albo C/C++ (co chyba bardziej prawdopodobne) po tym jak Oracle zaczyna powoli rozrabiać z Java'ą ;-) [a wolałem żeby Suna kupił Oracle niż IBM... ;-)]

Pierwszym szokiem dla Java'owca będzie to, że choć Go jest językiem obiektowym [także!] to nie ma tam klas!

Ale nie ma obaw, spokojnie możemy dodawać metody do typów danych. Jedyny wymóg by typ danych był w tym samym pakiecie co metody.

Java'owy kod w stylu:
public class Point {
private int x, int y;
public Point(int x,int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public float distanceFrom00() {
return Math.sqrt(x*x+y*y);
}
}

W Go wygląda mniej więcej tak:
type Point struct {
x int;
y int;
}
func (p *Point) GetX() int {
return p.x
}
func (p *Point) GetY() int {
return p.y
}
func (p *Point) DistanceFrom00() float {
return float(math.Sqrt(float64(p.x*p.x)+float64(p.y*p.y)))
}

Czyli definiujemy nowy typ danych, a później metody dla tego typu.
Wołanie metod jest dokładnie takie samo jak w Java'ie czyli po kropce.
Ze złych wieści, tu znów są wskaźniki :-( Na szczęście język trochę pomaga, i np. w deklaracjach metod nie trzeba wcale robić (p *Point) można zrobić (p Point).
To p to receiver, który robi za odpowiednik this.
Stąd w getterach jest użyte p.x.

Dziedziczenie jest, choć ciut inaczej zorganizowane.
Jeżeli np. stworzymy nowy typ Point3, w którym dodamy jeszcze z, to mamy wtedy:
type Point3 struct {
Point
z int
}

Trzeba doimplementować jeszcze GetZ() i nadpisać DistanceFrom00(), co wygląda tak:
func (p *Point3) GetZ() int {
return p.z
}

func (p *Point3) DistanceFrom00() float {
return float(math.Sqrt(math.Pow(float64(p.Point.DistanceFrom00()),2)+float64(p.z*p.z)))
}


Gorzej jest z tworzeniem tych obiektów :-(
p:=Point{3,2} // tworzy strukturę z x=3 i y=2
p3:=Point3{Point{3,2},1} // tworzy Point3 z x=3,y=2,z=1.......
p4:=new(Point) // tworzy nowy Point, w p4 jest wskaźnik do niego z x=0, y=0

Jak widać w tym fragmencie jest to ohydne ;-) dlatego jak rozumiem zaleca się tworzenie metod fabrykujących, które będą zwracały nasze obiekty.

Teraz ważna rzecz, w Go nie ma modyfikatorów dostępu takich jak w Java'ie, nie ma tu public, private czy protected, jest jednak sposób na ograniczanie widoczności.
Jeżeli nazwa pola, typu, czy metody jest pisana dużą literą to takie coś będzie widoczne poza swoim pakietem, wszystko pisane z małej litery widoczne jest tylko w pakiecie.
To wydaje się mieć sens, w Java'ie ewidentnie programiści przynieśli zwyczaje z C++ i to co było pomyślane jako mechanizm namawiający do używania modyfikatorów dostępu tak by to pakiety były głównymi strukturami decydującymi o prywatności stało się mechanizmem do prywatyzowania na poziomie klas.

Jak było widać wyżej przez to jak się "dziedziczy", można dość łatwo wprowadzić wielodziedziczenie, z tym, że jak 2 "dziedziczone" typy mają pola czy metody o tej samej nazwie to się robią problemy i puki ich nie używamy to jest dobrze, ale jak użyjemy to jest błąd [nie przyglądałem się temu jeszcze więc wieżę na słowo temu co czytałem ;-)].

W Go jest za to coś takiego jak interfejsy :-) Ale działają one kompletnie inaczej niż w Java'ie, w każdym bądź razie w sferze deklarowania tego czy się je implementuje.....
Jeśli coś ma odpowiednie metody to implementuje dany interfejs i nie trzeba niczego deklarować!
Popatrzmy na kod:
type Printable interface {
String() string
}
type TosterInt struct { value int }
type TosterFloat struct { value float }
func (i TosterInt) String() string {
return fmt.Sprintf("%d",i.value)
}
func (f TosterFloat) String() string {
return fmt.Sprintf("%f",f.value)
}

I teraz wszędzie w kodzie możemy używać cosiów stworzonych z TosterInt i TosterFloat tak jakby były typu Printable :-) Czyli trzymać je np. w mapie gdzie wartości są Printable.
  m:=make(map[string]Printable)
m["TosterInt"]=TosterInt{3}
m["TosterFloat"]=TosterFloat{3.9}
for k,v:=range m {
fmt.Println(k," ",v)
}


Aha, tak biegiem, podstawowy program w Go wygląda tak
package main

import "fmt" // tutaj importujemy co nam potrzebne, zwykle potrzebujemy ;-)

func main() {
// nadziewka
var i = 1 // samo nam stworzy inta o wartości 1
var f float64 = 1.0 // samo nam stworzy float64 o wartości 1
i1:=1 // to samo co var i1=1
fmt.Println(i," ",f," ",i1)
}

W Go można przypisywać jednym := kilka wartości, funkcje też mogą zwracać kilka wartości np:
package main

import "fmt"

func toster() (string, int, bool) {
return "string",1,false
}


func main() {
a,b,c:=toster()
fmt.Println(a," ",b," ",c)
}

Wypisze "string 1 false".
To wieloprzypisywanie trochę na początku przeraża ;-)

Ok, to tyle, jak będę miał nastrój na dalszą naukę to napiszę więcej ;-)
Na razie zachęcam do przyjrzenia się tutorialowi [szczególnie prezentacji do której linki są na stronie tutoriala].

Nie jestem już tak obrzydzony do Go jak rok temu, ale nadal nie jest to mój ulubieniec ;-)
http://www.blogger.com/img/blank.gif
Podoba mi się to, że jak na razie wydaje się nie skupiać na "architekturze", nie muszę myśleć o hierarchii klas, nie muszę pilnować ciągle by wszystko co powinno dziedziczyło/implementowało to co powinno, to się tu samo wydaje robić. Potrzebuję metody to ją po prostu dopisuję......

Na razie jednak nie wychodzi mi komplikacja z kilku plików ;-) Używam portu dla Windows, o którym tu już kiedyś pisałem i niestety nie potrafi on chyba do końca pracować z wieloma plikami [jeżeli stworzy się swój własny pakiet], dodatkowo gdy program zrobi out of memory to pod Windows cały komputer zawisa, i po jakichś 30 sekundach program po prostu kończy swoje działanie, bez żadnej informacji........

Do prostych zabaw warto użyć umieszczonego na stronie Go placu zabaw ;-)


Podobne postybeta
Wysyłamy pliki do Google Docs przy pomocy Go :-)
Język Go dla Windows :-)
Go dla Java'owca ;-) odcinek 2 "kontenery dwa ;-)"
Go wolniejsze od C i JavaScript, i ciut szybsze niż Java ;-) [a jednak od Java'y też wolniejsze]
clone() i Cloneable się mszczą ;-)

piątek, maja 07, 2010

Go dla Windows przyśpiesza :-)

No i jest nowa wersja Go dla Windows, tym razem kompilacja odbywa się już nie dla mingw, a dla Windows.Dlatego teraz zestaw zmiennych środowiskowych musi wyglądać ciut inaczej niż wyglądał wcześniej [przy założeniu, że go jest w katalogu c:\go]:
GOARCH=386GOBIN=c:\go\binGOOS=windowsGOROOT=c:\go
No i kod wynikowy jest już szybszy o jakieś 2.5 raza niż jeszcze kilka dni temu :-) Nie dostrzegłem jednak wśród pakietów niczego co sugerowałoby możliwość używania jakiegokolwiek GUI w programach w Go.To tyle :-)


Podobne postybeta
Język Go dla Windows :-)
W niewoli numerów wersji...
Raspberry Pi to nie jest demon prędkości ;-)
Dart - to działa i ma sens :-)
Żonglowanie to kolejna sztuczka w zasobniku programisty ;-)

wtorek, maja 04, 2010

Język Go dla Windows :-)

No i jest już port języka Go dla Windows :-)
Jest już jakiś czas, ale wcześniej go jakoś kilkukrotnie przeoczyłem.
Sportowano jak na razie tylko wersję 32 bitową, czyli narzędzia 8g i 8l [oraz parę innych, których się zwykle z linii poleceń nie używa ;-) albo w dostępnej "paczce" jest tylko 32 bitowa wersja, aż tak daleko nie czytałem].
Tutaj krótka instrukcja pracy z Go na Windows [stworzona na podstawie filmu "szkoleniowego", ale w końcu każdy kto chciałby używać Go na Windows wie jak stworzyć zmienne środowiskowe :-)].
  1. idziemy na stronę do pobierania portu Go dla Windows i pobieramy najnowszy plik
  2. kopiujemy katalog go z archiwum w miejsce gdzie byśmy go chcieli mieć, np. do c:\go [u mnie d:\Software\go ;-)] [czyli plik 8g powinien być pod ścieżką c:\go\bin\8g.exe]
  3. tworzymy 4 zmienne środowiskowe:
    GOARCH=386GOBIN=c:\go\binGOOS=mingwGOROOT=c:\go
  4. modyfikujemy zmienną środowiskową PATH i dodajemy na jej końcu %GOBIN% [oczywiście po średniku ;-)]
No i tada! mamy Go zainstalowane :-) [tak btw. ilu ludzi wie skąd się wzięło "tada!"? ;-)]
Teraz przydałby się jakiś program, np. Hello World, czyli tworzymy plik HelloWorld.go takiej treści:
package main

import "fmt"

func main() {
fmt.Print("Hello World!!!");
}
[tu ostrzeżenie, kompilator dla Windows lubi gdy ostatnia linia programu jest pusta, inaczej wyrzuca błąd]
Po tym kompilujemy program:

8g HelloWorld.go

kompilator stworzył nam plik HelloWorld.8, który musimy zlinkować przy pomocy komendy:

8l -o HelloWorld.exe HelloWorld.8

I teraz już wystarczy uruchomić program wynikowy HelloWorld.exe.
Programy jak na razie szybkością nie porażają ;-) Dla przykładu mój ulubiony program do testowania "szybkości" języków programowania, czyli powtarzane tu już do znudzenia całkowanie numeryczne funkcji e-x2 od -10 do 10 w 10000 kroków, wymaga na moim laptopie mniej więcej 7-8 ms na jedną iterację [czyli jeśli dobrze pamiętam jakieś 10 razy więcej niż wersja w C czy C++ skompilowana w Visual Studio].
Tutaj program:
package main
import "fmt"
import "math"
import "time"

func calc() float {
var sum float=0.0;
var start=0.0;
var stop=10000.0;
var d float=20.0/stop;
for i:=start; i<stop; i++ {
var x float=d*i-10.0;
sum=float(sum+float(math.Exp(float64(-x*x)))*(20.0/stop));
}
return sum;
}

func test() {
start:=time.Nanoseconds();
for i:=0; i<1000; i++ {
calc();
}
stop:=time.Nanoseconds();
var time = float64(stop-start)/1000/1000;
fmt.Printf("%f\n",float64((time)/1000));
}

func main() {
test();
}
Wyniki wyglądały przed chwilą tak:
8.473252
7.443193
6.397191
7.565200
6.411192
7.491195
6.493197
7.519197
Programy wynikowe do małych nie należą ;-) mają w przypadku obu tu przytoczonych blisko 700KB.
Jak na razie nie jestem entuzjastą Go, ale fakt, że do jego używania nie potrzebuję już uruchamiać VMWare Playera dużo ułatwia i może się mu trochę poprzyglądam.


Podobne postybeta
Go wolniejsze od C i JavaScript, i ciut szybsze niż Java ;-) [a jednak od Java'y też wolniejsze]
Raspberry Pi to nie jest demon prędkości ;-)
C# miewa swoje plusy ;-)
Go dla Java'owca ;-) odcinek 1 "klasy"
Wysyłamy pliki do Google Docs przy pomocy Go :-)

niedziela, listopada 15, 2009

"Powszechnie znane" prawdy o wydajności to często bujdy na resorach

Trochę mnie przeraża posługiwanie się "powszechnie znanymi" prawdami gdy mowa o wydajności.

"Java jest wolna", tak w każdym bądź razie twierdzi wielu. Jak pokazały między innymi moje testy, Java jest szybka. Momentami ociera się o wydajność porównywalną z C i C++, a zwykle jej wydajność jest tego samego rzędu co w przypadku tych dwóch języków.

"Chrome jest najszybszą przeglądarką", to tez tak "powszechnie znana" prawda.
Ale ja sam na swoich komputerach mam tak, że wszędzie bardziej responsywny, a więc dla mnie i szybszy jest Firefox. JavaScript Firefoksa w pewnych zadaniach też jest szybszy od tego z Chrome.
Prawdę mówiąc pierwszym komputerem na którym mogę używać Chrome bez obawy, że dostanę cholery czekając na pokazanie strony [po przełączeniu się z innej strony] jest mój nowy laptop, ale on ma 4GB RAM! tutaj nawet IE MUSI być szybki ;-)

"Linux jest szybszy od Windowsa". To też nie do końca prawda, szczególnie gdy chodzi o przełączanie wątków, które w Linuksie jest wolniejsze. Stąd np. wydajność klientów Seti@Home czy teraz Boing'a jest zwykle niższa na Linuksie niż pod Windows na tym samym sprzęcie.

"Szybkość komputera zależy głównie od szybkości procesora".
Też nieprawda. Największy wzrost wydajność zawsze zauważałem po zwiększeniu pojemności RAMu. Bo bądźmy szczerzy pod takim Windows, jeśli nie masz odpowiednio dużo RAM [teraz 4 GB to rozsądne minimum] to procesor Twojego komputera i tak będzie marnował miliardy taktów tylko na to by czekać aż mechanizm stronicowania przerzuci do RAM z dysku potrzebny kawałek pamięci.
Inna sprawa, że nawet sama szybkość procesora, mierzona w ilości rzeczy, które jest w stanie zrobić w jednostce czasu nie zależy wcale tak bardzo od taktowania, a bardziej od jego architektury, o czym już tu kiedyś pisałem porównując procesory Intel Celeron 900 MHz z Intel Atom 1.6 GHz.

Teraz zaś przyszła nowa "powszechnie znana" prawda, która mówi "Go jest szybkie". Nie, na razie jest tylko porównywalne do C/C++ i Java'y. Ma za sobą potencjał więc jest szansa, że będzie szybkie.
Ale trzeba przyznać, że kompilator Go JEST szybki i to bardzo :-)

Podobne postybeta
Celeron M353 900MHz vs. Intel Atom 1.6GHz, czyli o tym czemu jest remis? ;-)
O wyższości aplikacji natywnych nad tymi w HTML5 - od strony developera
Freakonomia, czy jak kto woli Freakonomics
A mnie tam jednak prosty model klimatyczny przekonuje do twierdzenia, że mamy wpływ na zmiany klimatyczne i że globalne ocieplenie może być faktem
Windows 8 - błeee, ciągle błeeee

piątek, listopada 13, 2009

Go wolniejsze od C i JavaScript, i ciut szybsze niż Java ;-) [a jednak od Java'y też wolniejsze]

[update: 17/11/2009 0:08 - pozmieniałem trochę treść wpisu żeby oddawał rzeczywiste wyniki :-)
update: 14/11/2009 1:06 - Oszukałem się ;-) Go wcale takie szybkie nie jest, jeśli zwrócicie uwagę na program w Go i te w innych językach to zauważycie istotną różnicę, wszystkie języki poza Go używały odpowiednika math.pow() czyli potęgowania, w Go użyłem przez pomyłkę math.exp(), różnica jest znacząca, bo po użyciu math.Pow() prędkość spadła do 8.521 ms na 1 iterację.
W Java'ie program używający math.exp() zamiast math.pow() potrzebuje na wykonanie 1 iteracji tylko 1.37 ms, a JavaScript w Firefoksie tylko 0.74 ms, C++ 32 bitowy zaś 0.5 ms.
Go więc szybkie nie jest, w podanym przykładzie program w Go jest wolniejszy od Java'y]

Google wypuściło swój nowy język o nazwie Go.
Nie ma go dla Windowsa, jest na razie tylko dla Linuksa i MacOSa.
Sam język mi się nie podoba. Szczególnie bałagan z brakiem konwersji typów.
Język jest przemądrzały i wie lepiej od Ciebie czego chcesz, czyli gdy użyjesz:


f:=10.0;
To zgadnie, że na pewno chcesz użyć typu float, ale gdy spróbujesz tego f użyć w miejscu gdzie Go oczekuje float64 to dostaniesz info o błędzie i tyle.
Żeby drania przechytrzyć trzeba użyć:


var f float64=10.0;
co już takie czytelne nie jest.
Ale rzeczywiście Go wydaje się szybkie.
Znów napisałem w nim całkowanie numeryczne ;-), którego kod poniżej:

package main

import "fmt"
import "math"
import "time"

func calc() float {
var sum float=0.0;
var start=0.0;
var stop=10000.0;
var d float=20.0/stop;
for i:=start; i<stop; i++ {
var x float=d*i-10.0;
sum=float(sum+float(math.Exp(float64(-x*x)))*(20.0/stop));
}
return sum;
}

func test() {
start:=time.Nanoseconds();
for i:=0; i<1000; i++ {
calc();
}
stop:=time.Nanoseconds();
var time = float64(stop-start)/1000/1000;
fmt.Printf("%f\n",float64((time)/1000));
}

func main() {
test();
test();
test();
test();
test();
test();
test();
test();
}
Wszystko uruchamiałem na Ubuntu 9.10 w VMware Player 3.0. I zaskoczenie, wynik jest całkiem niezły bo wynosi 3.183 milisekundy na 1 iterację [przy wykonywaniu math.Exp(), jednak wszystkie inne języki były testowane z liczeniem potęgi czyli math.Pow(), wtedy czas wynosi 8.521 ms na 1 iterację]. [Z czasu wykonania kodu dla JavaScript'u mogę wnosić, że różnica w prędkości wykonania między hostem Windows a systemem w VMPlayer wynosi jakieś 1.5, co dawało by jakieś 2.1-2.2 ms na 1 iterację ;-) [a w rzeczywistości 5.5-6 ms], nieźle, ale nadal wolniej od Java'y, która wykonywana w tym samym środowisku potrzebuje 2 razy mniej czasu na wykonanie tego samego zadania. Trzeba jednak pamiętać, że kompilator Go dla 32 bitów nie produkuje chyba najszybszego kodu, bo główny development odbywa się w wersji 64 bitowej. Trzeba też przyznać, że sam kompilator jest NAPRAWDĘ szybki :-)
Jako jednemu z niewielu produktów Google nie życzę temu językowi na razie zbyt dużych sukcesów ;-) i na razie to nazwałbym ten język Błe.. ;-)


Podobne postybeta
Język Go dla Windows :-)
Raspberry Pi to nie jest demon prędkości ;-)
Całkujący Dart ;-)
Go dla Java'owca ;-) odcinek 1 "klasy"
Plus dla Scala, minus dla Groovy ;-)