narzekanie

znowu się rozchorowałem.

na dodatek muszę pisać dokumentację do bazy. piszę w docbooku bo jest zasadniczo fajny. zasadniczo. ktoś wie jak w nim zrobić tabelkę z nagłówkiem pionowym a nie poziomym? nie chodzi mi o kierunek czcionek. po prostu chcę mieć “header-column" a nie “header-row".

a do tego nie mam na nic czasu. ilość nieprzeczytanych newsów w akregatorze przekroczyła 5000.

no nic. może w weekend się trochę “odkuję". jak tak, to zarzucę was lekko nieświeżymi newsami. ale za to w dużej ilości 🙂

drobny błąd

a dziś napiszę o tym jakim to łosiem można być. niechcący.

na potrzeby jednego z projektów napisałem własnego orm'a (object-relationship mapper). nie znacie? takie cos co pozwala widziec rekordy z tabel jako obiekty. ogólnie – każdy orm jest bez sensu. mój tym bardziej, ale służył do prostego celu – uproszczenia robienia eksportów.

działał.

do czasu.

ostatnio na jednej z maszyn eksporter zaczął zżerać cały ram. calutki. i wywalać maszynę. usiadłem do debugowania. i oto co ujrzałem:

...
sub _table { my $self = shift; return $self->{ 'table_name' } }
sub _db    { my $self = shift; return $self->{ 'db' } }
sub _log   { my $self = shift; return $self->{ 'log' } }
sub _refresh {
my $self   = shift;
my $sql    = sprintf 'SELECT * FROM %s WHERE id = ?', $self->_table;
my $record = $self->_db->get_single_record( $sql, $self->{ 'data' }->{ 'id' } => 'INT8' );
if ( $record ) {
$self->{ 'data' }    = $record;
$self->{ 'fetched' } = 1;
return;
}
$self->log->critical(
"Cannot refresh record data from table " . $self->_table . " for id = " . $self->{ 'data' }->{ 'id' } );
croak( "DB Error" );
}
sub _get {
my $self = shift;
my ( $field ) = @_;
$self->_refresh unless $self->{ 'fetched' };
return $self->{ 'data' }->{ $field };
}
sub AUTOLOAD {
my $self   = shift;
my $method = $AUTOLOAD;
$method =~ s/.*:://;
return unless $method =~ m{ \A [a-z][a-z0-9_]* \z }xmso;
return $self->_get( $method );
}

zasada działania bardzo prosta – jeśli mam obiekt klasy dziedziczącej z tego orm'a, i wykonam na nim metodę:

$obiekt->jakies_pole

(gdzie jakies_pole nie jest nazwa istniejacej metody), to request trafi do autoloada, który wywoła _get. _get sprawdzi czy obiekt załadował z bazy dane. jak tak – zwróci odpowiednie pole i po sprawie.

a co jeśli nie?

wtedy kod trafia na _refresh(). refresh odczytuje cały rekord z bazy w oparciu o id (które musi być). fajne.

jedno pytanie: co się stanie gdy rekordu w bazie nie będzie?

tradycyjna odpowiedź: kod zaloguje informacje o błędzie i wykona croak(). czyli taki die.

ale nie. niestety. złośliwy los i brak dobrych oczu spowodował, że napisałem $self->log->(), podczas gdy obiekt loggera jest dostępny przed $self->_log.

efekt? metody log nie ma. trafiamy na autoloada. autoload odsyła do _get'a, _get do _refresha. _refresh znowu nie znajduje rekordu, więc … i kółeczko się zamyka.

nieskończona rekurencja, 3 giga zużytej pamięci, kilka godzin pracy paru osób. przez brak jednego “_".

a czemu o tym piszę? abym pamiętał. i sprawdzał kod. i bym miał okazję się pochwalić jakie “fajne" błędy potrafię wygenerować, a potem wykryć. i pochwalić “perl -d" – debugger jest wkurzający, mało sympatyczny. i ratuje d… jak oczy zawiodą.

aha. i jak fajnie wygląda “T" pod debuggerem po np. 50 przebiegach tej rekurencji 🙂 (T == stack trace).

miejski samochód

massachusetts institute of technology – jedna z najbardziej znanych uczelni technicznych na świecie. i do tego miejsce które co chwilę ma nowe fajne projekty badawcze.

tym razem badacze z mit wymyślili nowy samochód. miejski. na czym polega jego “nowość"? na modelu używania, ilości zajmowanego miejsca itd.

ponowie opracowali samochód 2 osobowy który można “składować" jak wózki w supermarkecie. działa na silnik elektryczny i ma interesujący model działania/używania. mianowicie nie miałby to być samochód do kupienia. idea jest taka, że miasto kupuje ich dużo, rozmieszcza w potrzebnych miejscach. a użytkownicy? podchodzą do dowolnego samochodu, wsiadają i jadą. płacą kartą przy użyciu. minus – muszą odstawić na miejsce. niekoniecznie to z którego wzięli – wystarczy dowolny “parking" tych samochodzików.

nie jest to na pewno samochód na długie podróże. ale na proste “podjechanie do klienta" czy “skoczenie do sklepu" – może się okazać wystarczający. pomysł ciekawy.

na stronie boston globe można znaleźć artykuł, ale co ciekawsze – flashową prezentację tego jak to ma działać.

porównanie implementacji ruby’ego

dzięki znajomemu (hi tmarc) dowiedziałem się o ciekawym tekście. autor porównał w nim wydajność kilku (41) testów w różnych implementacjach języka ruby.

udział wzięły kanony:

  • ruby 1.8 (na linuksie i na windows vista
  • ruby 1.9

ale także wersje mniej standardowe:

  • jruby
  • gardens point ruby .net (wersja beta, na windows vista)
  • rubinius
  • cardinal

porównano wydajność każdej z implementacji w stosunkdu do złotego wzorca – czyli 1.8 na linuksie.

efekt? no cóż. 1.9 zdecydowanie rządzi. ruby 1.8 na linuksie ma drugie miejsce. wersja na windowsach jest trochę wolniejsza, ale (co ważniejsze) wywala się na 2 testach!

pozostałe implementacje: wolno i kiepsko. “hitem" jest cardinal – większość testów zakończona błędem, dwa trwały powyżej  15 minut i zostały ręcznie ubite (te testy były “zrobione" przez 1.8 w czasach 9.5 i 0.5 sekundy!). choć trzeba przyznać, że w 3 testach cardinal osiągnął najlepszy wynik. wydajnościowo gorszy był rubinius, ale on miał mniej errorów (“ledwie" koło połowy).

można spojrzeć by rozwiać złudzenia, lub nauczyć się czegoś z testów.

nowa technologia kości ram

ibm ogłosił, że opracowali właśnie nową technologię produkcji kości ram.

nowe kości są rozwinięciem idei i metody produkcji dram, ale prędkością zbliżone do sram. czyli około 2 krotnie szybsze od obecnych kostek.

sram od zawsze był szybszy, ale te kości były sporo większe niż standardowe dramy. więc się nie przyjmowały w standardowych zastosowaniach. teraz jednakże – gdy nowy dram ma osiągnąć wydajność sram, można liczyć na spory przełom.

poza zwiększoną szybkością nowe kości mają być też pojemniejsze. trzykrotnie!.

podsumowując: 3 razy więcej ramu, działającego 2 razy szybciej. ciekawe tylko kiedy to wejdzie do seryjnej produkcji i sprzedaży – na razie ibm szacuje, że pierwsze handlowe kości pojawią się w 2008 roku i będą to pamięci serwerowe. inne typy pamięci pojawią się później. a kiedy do laptopów?