sysd.org
18jul/121

Terminal Velocity

 

Não, não se trata de um fenômeno físico, nem de um videogame, e muito menos de um filme com Charle Sheen. Já que passo a maior parte do dia na frente de um emulador de terminal (a famosa "tela preta com as letrinhas"),  observei que em alguns casos a user experience (se é que posso falar assim de CLI) é mais fluida e agradável do que em outros.

Em outras palavras, bandwidth de saída de caracteres na tela é bastante variável.

Isso é evidente em programas que subvertem a ideia do texto linear, os fabulosos TUI, tais como Vim ou Midnight Commander. Não é tão evidente em libcaca ou icat, pois são poucas as pessoas que sabem o que é isso e um número ainda menor encontra alguma utilidade para eles.

Felizmente, tendo reduzido "usabilidade" em "bandwidth", quantificar a métrica se torna fácil. É só pegar um texto grande, jogar na tela e cronometrar. "Texto grande", no caso do meu teste, foi o código-fonte do Perl v5.16.0, "colorificado" através de source-highlight:

find ~/perl-5.16.0 -type f -name '*.[cht]' -or -name '*.p[lm]' -exec \
    source-highlight --failsafe --infer-lang -f esc --style-file=esc.style -i {} \;

Depois, listei esse arquivo em cada emulador de terminal, dentro de VMs respectivos de cada OS (isso é, VM de Linux, de Windows e de Mac OS). VM fez-se necessário para "nivelar por baixo": seria injusto comparar VMs de Windows e Linux com o Mac OS nativo. Não mexi em configurações/preferências dos emuladores de terminal: fontes, cores e tamanho da tela são os default de cada "fabricante". O resultado está no gráfico no começo do post, e também nessa tabela:

Terminal Time (sec)
iTerm2.app (Mac) 12.72
Terminal.app (Mac) 41.03
xterm (Mac) 41.52
mintty (Win32) 14.86
xterm (Linux) 29.70
Gnome Terminal (Linux) 61.68
80x24 text-mode console (Linux) 276.68

O que salta aos olhos é que justamente o Linux, o sistema que contribuiu tanto para o "revival" do CLI, é o que tem emuladores de terminal mais lentos. E o terminal mais simples (aquele que no Linux é acessível via Ctrl+Alt+F1; a telona DOS clássica) é, contra-intuitivamente, o mais ineficiente!

É claro que esse benchmark é muito tosco. Talvez seria mais representativo utilizar a mesma fonte em todos os terminais testados, e também maximizar a tela dos mesmos (a quebra de linhas longas costuma ser custosa), além de desabilitar o histórico de scrollback. Fonte com/sem antialiasing e uso/não-uso de ANSI escape sequences também interferem na velocidade da saída. Mas, enfim: a diferença de velocidade é suficientemente grande e perceptível. Portanto, duvido muito que algum ajuste fino deixará Gnome Terminal mais rápido do que iTerm2.app.

14jul/121

InterNOT Explorer

Antes de me taxarem de hater ou fanboy: já usei muito o Internet Explorer. Também já usei muito o Netscape, Mozilla, Opera, Firefox e Chrome. E "muito", para mim, traduz como "por mais de um ano". Só não usei o Safari pois a primeira coisa que fiz ao migrar para Mac foi instalar um navegador familiar, para não se sentir tão deslocado.

Acredito que usei todos esses navegadores no seu auge, dadas as circunstâncias: Opera era imbatível nos Lentium com 32MB de RAM da faculdade. Firefox era absurdamente mais leve do que o Mozilla, e tão completo quanto. Depois que engordou, migrei pro Chrome. Netscape Gold não tinha muitas alternativas na época do Windows 3.11. E o Internet Explorer... Por um bom tempo estava na vanguarda, era leve e com recursos (proprietários) muito interessantes.

Como sempre acontece, tudo o que sobe, tem que descer. Hoje, todos os webdevelopers odeiam o Internet Explorer e vibram com a perda do browser share pelo mesmo, porém, parafraseando o Mark Twain, "os rumores sobre a sua morte são, sempre, um tanto exagerados". Independente da métrica adotada (pois, dependendo da métrica, o share do IE varia de 16.7% a 32.31%, na metade de 2012), o declínio da popularidade é evidente.

Esta seria a história do lado dos usuários. Mas o que me chamou atenção, recentemente, é a história do lado dos webdevs. Especialmente essas três notícias:

  1. Startup afirma ter economizado 100 mil Obamas deixando do lado a compatibilidade do seu produto com o Internet Explorer;
  2. Online shop cria "imposto Internet Explorer": clientes usando esse navegador pagam mais (a justificativa é a dificuldade de manter uma versão compatível do site);
  3. jQuery 2.0 abandonará o suporte a Internet Explorer 6, 7 e 8.

Seria equivocado afirmar que são essas as medidas que colocarão os últimos pregos no caixão do infame navegador da Microsoft. Para mim, estas são as evidências de que o seu share está, de fato, baixo o bastante para ser desprezado.

2jun/122

Google Refine + Perl (English)

(Portuguese version here)

Google Refine is awesome. If you're unaware of what it is, access their official page and watch at least the first screencast. You'll see it can be helpful for several ETL-related tasks.

Currently, I use it a lot, specially for simple (but boring) tasks, like loading a CSV, trimming out some outliers and saving as JSON to be imported into MongoDB. Nothing a Perl one-liner couldn't do.

However, the opposite is not true: Perl one-liners are a lot more flexible than Google Refine. Now, what if we could merge both?

  1. Google Refine could be easily integrated with any RESTful API.
  2. Perl transforms one-liners into RESTful webservices.
  3. PROFIT!!!

As a practical example, I'll use some georeferenced data I was working at. Let's suppose I have to deduplicate registers, and one of "duplicate" rules is their proximity on the map. Google Refine is far from a full-featured GIS, and is unable to handle bidimensional coordinate system. Enter the GeoDNA: an algorithm to lower geospatial dimensions. As it's FAQ says,

GeoDNA is a way to represent a latitude/longitude coordinate pair as a string. That sounds simple enough, but it's a special string format: the longer it is, the more accurate it is. More importantly, each string uniquely defines a region of the earth's surface, so in general, GeoDNA codes with similar prefixes are located near each other. This can be used to perform proximity searching using only string comparisons (like the SQL "LIKE" operator).

Another interesting property of GeoDNA is that when ordening a set of records by their GeoDNA code, close locations are likely to appear in adjacent rows (sometimes, close locations will share very different prefixes, but similar prefixes always represent close locations).

To incorporate GeoDNA into Google Refine, we'll use the Add column by fetching URLs option, clicking on the header of any column (which column it will be doesn't matter as we'll use two of them, anyway):

As the expression, we'll paste the following code (here, pay attention to the correct latitude/longitude column names):

'http://127.0.0.1:3000/?lat='+
row.cells['latitude'].value
+'&lon='+
row.cells['longitude'].value

Throttle delay can be zeroed, as our webservice is local. The final configuration should look like this (don't push the OK button, yet):

Now, check if you have Mojolicious and Geo::DNA Perl modules (install them via CPAN, if not) and paste into your terminal:

perl -MGeo::DNA -Mojo -E 'a("/"=>sub{my$s=shift;$s->render(json=>{geocode=>Geo::DNA::encode_geo_dna($s->param("lat"),$s->param("lon"))})})->start' daemon

If you prefer a "human-readable" version, paste the following code into geocode-webservice.pl:

#!/usr/bin/env perl
use Geo::DNA qw(encode_geo_dna);
use Mojolicious::Lite;
 
any '/' => sub {
    my $self = shift;
    $self->render(json => {
        geocode => encode_geo_dna(
            $self->param('lat'),
            $self->param('lon'),
        ),
    });
};
 
app->start;

Once you started a webservice, it will report Server available at http://127.0.0.1:3000. Now, click OK on Google Refine dialog and wait. Even without delay, it could be a bit slow; however, even then this hack saved me a lot of time 😉