Blog do Eduardo Costa Meu blog pessoal

31Out/110

Santa Ignorância, node.js!

Já faz um tempo que estou brincando com o node.js em casa e consegui uns números interessantes (800 requisições por segundo em uma t1.micro na Amazon). Pensei então: quanto atingiria um "hello world" na máquina i7 com oito cores que tenho no trabalho?

Vamos à experiência! O código é assombroso de tão simples:

var http = require("http");
http.createServer(function(request, response) {
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end("ok");
}).listen(8000);

Qualquer requisição feita na porta 8000 gera uma resposta "200" com o texto "ok". Vamos executar o "ab" (ApacheBench):

$ ab -n 10000 -c 100 http://localhost:8000/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
 
Benchmarking localhost (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests
 
Server Software:        
Server Hostname:        localhost
Server Port:            8000
 
Document Path:          /
Document Length:        2 bytes
 
Concurrency Level:      100
Time taken for tests:   0.736 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      660000 bytes
HTML transferred:       20000 bytes
Requests per second:    13587.64 [#/sec] (mean)
Time per request:       7.360 [ms] (mean)
Time per request:       0.074 [ms] (mean, across all concurrent requests)
Transfer rate:          875.77 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       3
Processing:     1    7   3.5      7      19
Waiting:        1    7   3.5      7      19
Total:          2    7   3.4      7      19
 
Percentage of the requests served within a certain time (ms)
  50%      7
  66%      9
  75%     10
  80%     10
  90%     11
  95%     13
  98%     16
  99%     17
 100%     19 (longest request)

Repare na quantidade de requisições por segundo. Sim, IT'S OVER NINE THOUSAND! Só para comparar, fiz alguns Hello World's na mesma máquina:

  • Apache (instalação default do ubuntu) gerou 25 mil para o index.html!
  • Apache+PHP com um "echo ok" gerou 21 mil!
  • Apache+Perl gerou 3 mil
  • Rails no WEBrick (trocando o index dele pelo index.html do httpd do ubuntu) aguentou "apenas" 800 requisições por segundo (e ainda tomei alguns muitos "connection reset" no meio dos testes)

Eu pensei em testar com Java e Python também, mas Python está longe de meus conhecimentos para um Hello World "quick-and-dirt" e, em Java é impossível fazer um "index" em menos de cinco minutos sem ter o ambiente pré-pronto (ou seja, preciso instalar o Tomcat, criar um projeto no NB, criar um Servlet, etc etc).

E, antes de mandarem comentários xingando minha metodologia de testes, reparem que todos os exemplos são instalações "vanilla" sem nenhuma configuração. Eu achei os números do node.js interessantes e quis mostrar, comparando com outras tecnologias que permitem um "Hello World" saindo do forno em menos de 5 minutos.

No final, dá a impressão que o Apache é bem mais rápido que o node.js, porém o httpd usa N processos! O node.js, por outro lado, é 100% monothread (event-driven ao extremo) - por isso não escala legal em oito cores. Tentei procurar por uma solução multi-core para o node.js, mas sem sucesso (tanto o módulo "cluster" quanto o "multi-node" não funcionaram).

Mas, vamos ser sinceros: 13 mil requisições por segundo usando um único core é fora de escala! Em um ambiente como na Amazon, posso rapidamente fazer um cluster de nodes usando máquinas t1.micro ou m1.small e um ELB para balancear. E, a parte engraçada é: com 13 mil requisições por segundo, nem precisa de cluster! Isso praticamente aguenta um Twitter (a antiga versão Rails precisou segurar 11 mil)!

O node.js pode ser uma plataforma baixo-nível, mas, com as libraries corretas e frameworks "home made", é uma poderosa ferramenta para a web!

30Out/112

Ponto Flutuante

Estou chegando a conclusão que ninguém nesse mundo lembra como funciona o conceito de "ponto flutuante" na programação. Em uma semana, já tive notícia de uns três ou quatro casos de pessoas falando "não sei porque a soma de decimal às vezes dá um resultado errado".

Vamos começar a aula esclarecendo que conta decimal não pode dar divergência. O que com certeza está acontecendo é que você está usando pontos flutuantes. Tirando COBOL e dBase III, não conheço nenhuma outra linguagem de programação na qual você use pontos decimais numa literal (ex: "83.27") e a linguagem interprete como decimal. Até que alguém prove o contrário, assuma que ela usa pontos flutuantes.

E, antes que alguém diga: "Ah, mas o meu não é float, é double.", vou avisando que "double" quer dizer o dobro de bits de representação, e não o dobro de precisão. Continua sendo ponto flutuante.

Como funciona? Em uma linha: o número é representado como Nx2^M. Lembra de notação científica (Nx10^M)? Mesmo princípio, só que usando base 2 (pois é essa a base que um CPU binário conhece). O número em ponto flutuante consiste de uma "base" N e uma "mantissa" M. Exemplo: N=2 e M=-4 é a representação PF para 2/16 ou 0,125. Como N e M tem uma quantidade finita de bits, claramente vão existir números não-representáveis em PF (ex: 10000000,000000001 - clique aqui e veja).

Se Nx2^M não é preciso, imagine a soma de Nx2^M e Ox2^P! Isso, "computacionalmente falando", significa transformar as mantissas M e P para um valor comum (Q), adaptando as bases N e O, efetuar a soma [Nx2^(M-Q)+Ox2^(P-Q)]x2^Q e normalizar o resultado. Preciso elaborar uma prova matemática para dizer que esse monstro é impreciso? A prova em JavaScript você vê clicando aqui. Mas, por via das dúvidas, se quiser uma prova mais formal, lembre que [Nx2^(M-Q)+Ox2^(P-Q)] vira a nova base, então ela precisa caber nos n bits da base durante a conta!

Resumo da ópera para quem gosta de decorar regra: não use ponto flutuante para valores monetários.

30Out/112

Onda de Preservação

Recebi esta aqui de meu amigo Flávio. É uma verdade tão "inconveniente" que eu poderia dedicar horas falando do porquê é verdade:

Na fila do supermercado o caixa diz a uma senhora idosa que deveria trazer suas próprias sacolas para as compras, uma vez que sacos de plástico não eram amigáveis ao meio ambiente. A senhora pediu desculpas e disse: “Não havia essa onda verde no meu tempo.”

O empregado respondeu: "Esse é exatamente o nosso problema hoje, minha senhora. Sua geração não se preocupou o suficiente com  nosso meio ambiente. "

"Você está certo", responde a velha senhora, nossa geração não se preocupou adequadamente com o meio ambiente.

Naquela época, as garrafas de leite, garrafas de refrigerante e cerveja eram devolvidos à loja. A loja mandava de volta para a fábrica, onde eram lavadas e esterilizadas antes de cada reuso, e eles, os fabricantes de bebidas, usavam as garrafas, umas tantas outras vezes.

Realmente não nos preocupamos com o meio ambiente no nosso tempo. Subíamos as escadas, porque não havia escadas rolantes nas lojas e nos escritórios. Caminhamos até o comércio, ao invés de usar o nosso carro de 300 cavalos de potência a cada vez que precisamos ir a dois quarteirões.

Mas você está certo. Nós não nos preocupávamos com o meio ambiente. Até então, as fraldas de bebês eram lavadas, porque não havia fraldas descartáveis. Roupas secas: a secagem era feita por nós mesmos, não nestas máquinas bamboleantes de 220 volts. A energia solar e eólica é que realmente secavam nossas roupas. Os meninos pequenos usavam as roupas que tinham sido de seus irmãos mais velhos, e não roupas sempre novas.

Mas é verdade: não havia preocupação com o meio ambiente, naqueles dias. Naquela época só tínhamos somente uma TV ou rádio em casa, e não uma TV em cada quarto. E a TV tinha uma tela do tamanho de um lenço, não um telão do tamanho de um estádio; que depois será descartado como?

Na cozinha, tínhamos que bater tudo com as mãos porque não havia máquinas elétricas, que fazem tudo por nós. Quando embalávamos algo um pouco frágil para o correio, usamos jornal amassado para protegê-lo, não plastico bolha ou pellets de plástico que duram cinco séculos para começar a degradar.

Naqueles tempos não se usava um motor a gasolina apenas para cortar a grama, era utilizado um cortador de grama que exigia músculos. O exercício era extraordinário, e não precisava ir a uma academia e usar esteiras que também funcionam a eletricidade.

Mas você tem razão: não havia naquela época preocupação com o meio ambiente. Bebíamos diretamente da fonte, quando estávamos com sede, em vez de usar copos plásticos e garrafas pet que agora lotam os oceanos. Canetas: recarregávamos com tinta umas tantas vezes ao invés de comprar uma outra. Abandonamos as navalhas, ao invés de jogar fora todos os aparelhos 'descartáveis' e poluentes só porque a lámina ficou sem corte.

Na verdade, tivemos uma onda verde naquela época. Naqueles dias, as pessoas tomavam o bonde ou de ônibus e os meninos iam em suas bicicletas ou a pé para a escola, ao invés de usar a mãe como um serviço de táxi 24 horas. Tínhamos só  uma tomada em cada quarto, e não um quadro de tomadas em cada parede para alimentar uma dúzia de aparelhos. E nós não precisávamos de um GPS para receber sinais de satélites a milhas de distância no espaço, só para encontrar a pizzaria mais próxima.

Então, não é risível que a atual geração fale tanto em meio ambiente, mas não quer abrir mão de nada e não pensa em viver um pouco como na minha época?

Categorias: sandbox 2 Comentários
29Out/110

Saudade dos 28 minutos

tinha dado adeus à promoção dos 28 minutos do Habib's - cortesia da Dilmarionete. Agora, veio o inevitável: a qualidade na entrega absurdamente cara do Habib's fez um bungee jump sem corda. Pedi uma pizza portuguesa e, quarenta e cinco minutos depois (sim, os 28 viraram 45), descobri que a portuga virou peperoni. Um erro bobo: só trocaram ervilha, cebola, ovo e presunto por um salame apimentado. Quase não se nota a diferença.

Vamos reclamar no disque-habib's, que antigamente tinha o aconchegante nome "Alô Tia Edna". Disque cinco para reclamações. Cinco. Opção inválida. WTF? Sim, a opção "reclamações" na URA foi estrategicamente configurada para enviar para "/dev/null". Sete minutos depois (ou seja, 53 minutos de autodigestão gástrica catalisada pelo nervosismo) aparece uma atendente que fez o pedido para troca da pizza. Espera... Troca? Vão levar a antiga e fazer o que? Qualquer coisa diferente de jogar no lixo é altamente anti-higiênico e provavelmente deve ser proibido pela ANVISA. Dica de amigo: pense duas vezes antes de comer algo frio no Habib's.

Para ficar mais divertido, pergunto delicadamente: "qual o prazo de entrega?" A resposta: "é o tempo de preparo e transporte". Ahn... Sério? Não vai contar o tempo para um funcionário nascer, crescer, estudar, tirar péssimas notas e ir para o Habib's, receber treinamento, mais o tempo para a criação e construção do forno, do plantio dos ingredientes "naturais", etc etc? Então vai ser mais rápido que eu esperava! Educadamente perguntei: "numericamente falando, quantos minutos isso quer dizer?" Resposta: "não temos como informar". Ou seja, pode levar 5 minutos ou 50 ou 500 (ou qualquer valor em R+). Tão preciso quanto jogar uma moeda e descobrir qual número dará na próxima loteria. Até a pior das pizzarias chutam um número qualquer. O recordista foi uma hora e meia. É um absurdo, mas deu um prazo!

Depois de debater mais uns 8 minutos com a cidadã, decidi desistir e pensar se devo comer a pizza errada ou esperar. A redonda estava em curso (dizia a lenda). Eu poderia esperar mais um tempo X, no qual X está entre zero e infinito ou comer a peperoni. Definitivamente a fonte inexorável de dor que um dia foi meu estômago me fez aceitar a idéia de comer a pizza fria que deveria ser devolvida.

Após deixar os ácidos estomacais trabalhando em algo diferente das paredes de meu trato digestivo, chega o motoboy com a pizza para trocar. Eu falei, já nada educadamente, que eu cansei de esperar e comi. Ele, com a cabeça fria que eu precisava no momento, disse: "Tudo bem. Se quiser, pode pegar essa aqui também." Ou seja, o funcionário provavelmente mais mal-remunerado, mal-valorizado e com menor autonomia nas decisões fez o que era o mais correto desde o início. Pedi desculpas pelo nervosismo, peguei a pizza e a pessoa com mais sensatez do dia respondeu dizendo: "relaxa". Com tanta gentileza dele nesse mundo atual, aposto que o coitado não dura muito lá.

29Out/110

Vantagens de ser ex-presidente

Imagina a cena: você sente algo errado na garganta e vai no médico no mesmo dia. Não falei de pronto-socorro! Vai direto ao médico. E não é no "postinho" do bairro. Você vai no Sírio Libanês. O médico banca o House, suspeita de câncer e te passa uma bateria de testes. PARA O DIA SEGUINTE. Sim, exames complexos (inclusive uma biópsia) no dia seguinte! No Sírio Libanês!

Quem conseguiu essa façanha não foi um mega-empresário ou um chefe de estado. Foi o ex-presidente Lula. Hoje, é um zé-ninguém. Não é um chefe de estado, não tem imunidade parlamentar, nem pode viajar com dinheiro público (ou seja, com NOSSO dinheiro).

Direitos iguais, né? Totalmente igualitário. Saúde universal. Zé-mané que nem eu ou você vai ao PS com incômodo na garganta e aguarda na fila até o dia seguinte para ficar cinco minutos com o médico e receber uma receita de xarope (sem codeína), nenhum exame, e a tentativa de marcar um otorrino para, no mínimo, daqui a uns dois meses. Não tem plano de saúde? No SUS você sai sem a receita, dois dias depois, talvez com uma bronca do médico por desperdiçar o tempo dele com bobagens, e sem chance de marcar um otorrino antes de seis meses. Alguma técnica mais avançada que a mão de um médico só vai ser empregada quando o tumor estiver tão protuberante na sua garganta que você já morreu por falta de ar ou adquiriu um "pomo-de-caim" ou simplesmente o benigno virou maligno e você descobre que vai precisar parcelar seu próprio caixão mais a gaveta mortuária (cova só para elite) em 24 meses - a boa notícia é que você não irá pagar todas as parcelas.

Enquanto isso, quantos Albert Einsteins, Mozarts, Camões, Pasteurs, não estão morrendo sem deixar seu legado para a humanidade? Quem sabe uma "Teoria Unificada", uma "Cura para o Câncer" ou mesmo uma bela sinfonia foi para o caixão sem nunca ter saído da cabeça de seu criador?

Vamos ser sinceros, diretos e racionais: qual contribuição o Lula vai dar para a humanidade a partir de agora? Ministrar palestras ou escrever um livro sobre sua própria vida? Sobre como ele abandonou os estudos, sem faculdade, não sabe nem a língua-pátria direito e virou presidente? Pode ser uma boa: desafogaria as faculdades, deixando lá só quem tem realmente interesse.

26Out/110

Vantagens de ser nerd

Uma das vantagens de ser Nerd (com "N" maiúsculo e negrito), é ver isso aqui na documentação de uma lib e poder rir até chorar:

sdb.createDomain('domain',function(err,res,meta){
  if( !err ) {
    console.log('Mul-ti-pass!')
  }
}

Dica: precisa ter visto (e gostado) de um certo filme para entender.

Categorias: geek Sem Comentários
23Out/110

Two and a Half Man – Nona Temporada

Na minha opinião, a temporada final. Assisti pela Apple Store e, como imaginei, é uma droga. Começa com o funeral do Charlie. As "ex" dele estavam lá e as piadas foram legais. Entretanto, sem continuidade nenhuma - como se fosse uma série nova: Chelsea (Jennifer Bini Taylor) e Courtney (Jenny McCarthy) disseram que Charlie passou DST para elas - algo que nunca foi dito antes por nenhuma das duas, mesmo sendo personagens regulares. A Courtney até saiu da oitava sem ódio algum - como então ela iria querer "cuspir no túmulo" dele?

Pela história, ele morreu em Paris, num acidente de trem. "Explodiu como um bolo de carne", segundo a Rose (Melanie Lynskey). Claramente Chuck Lorre declarando que não tem interesse em trazer o Charlie Sheen de volta. Apesar do óbvio clima de rancor, deu para rir até aparecer o seu "substituto". Na cena da venda da casa, nota-se que as risadas ao fundo e as ovações tentam forçar o público a se entrosar, mesmo quando os atores convidados são pouco conhecidos ou quando as piadas só tem graça para os que odeiam o Charlie Sheen.

A aparição de Ashton Kutcher foi forçada ao extremo. Ele fica nu duas vezes no mesmo episódio. Tentativa desesperada de agradar ao público feminino - afinal, nem as mulheres aparecem nuas nesse seriado! E olha que se 1% delas tivessem aparecido nuas do jeito que o Ashton apareceu, o seriado seria barrado em muitos países!

Ainda sobre o substituto, a atuação foi patética. Ele faz um papel de bilionário com o coração partido e suicida (que se cura miraculosamente e já pega duas mulheres de uma só vez logo no primeiro episódio). Basicamente, uma mistura do personagem chorão do Jon Cryer com a falta de inteligência do Jake (Angus T. Jones) mais o dinheiro e boa pinta do Sheen.

Podem falar o que for, mas essa mistura só dava certo com a "fórmula original". Só a atuação do Sheen ou as idéias do Lorre não levam esse seriado para frente. Agora, com certeza, vai cair na mediocridade.

23Out/110

Comprando na Apple Store americana

Sim, após meses de muita luta, pesquisa, sangue, suor, lágrimas e filosofia, consegui criar uma conta na Apple Store americana e comprar algo que normalmente só está disponível para os americanos.

Sim, é possível viver um pouco mais longe da marginalidade da pirataria. Tecnicamente, ainda não é 100% válido pois não sou americano (deveria ser para fazer o que fiz), mas ninguém saiu prejudicado de qualquer forma nessa transação.

Vamos aos passos:

  1. Compre um Gift Card da Apple Store (no e-Bay, por exemplo);
  2. Consiga um endereço americano qualquer no Google;
  3. Crie um cadastro na Apple Store americana usando esse endereço, nenhum cartão de crédito (basta não preencher) e coloque o número do Gift Card no campo "Redeem a gift card".
  4. DIVIRTA-SE com sua conta "pré-paga"

É um caminho fácil, muita gente já o fez antes com variações. Meu mérito está apenas em descobrir que o campo "Redeem" torna o campo do cartão opcional. Daí, fica como uma conta pré-paga de celular.

Vamos aos fatos: filme do Thor lá está em US$19. No Brasil, está uns R$40. Opa, esqueci de dizer que esse valor, na Apple Store, é para a versão em HD! Um Bluray no Brasil nem quero ver o valor. Ou seja, fica bem mais acessível ver um material que preste!

Outra parte boa é que eu comprei um episódio da nova temporada de Fringe para testar (ainda nem saiu aqui!), veio em HD (uhu!) e ainda ganhei o SD de brinde! Posso ver no meu iPod Touch 2nd-gen (SD) e no meu iPad 2 (HD) sem problemas! Ou seja, o HD vale por dois!

A desvantagem é a "taxa simbólica" que os americanos cobram na hora de vender o Gift Card. Comprei um de US$10 (o menor deles) por US$13. Mas, espantosamente, ainda é mais vantagem que comprar o mesmo kit no Brasil. US$ 26 por um filme HD recém-lançado é uma pechincha! Além, claro, do fato que você tem, no máximo, legendas em inglês (Closed Caption, na verdade). Não é um problema para quem sabe inglês (ou para quem está diligentemente estudando).

Ah, lembrando que, tirando os aluguéis (sim, é possível alugar filmes em HD também, US$ 5 pelo Thor), todo o conteúdo é seu ad-eternum. A menos, claro, que você cometa alguma asneira, que nem compartilhar sua senha ou divulgar seu usuário!

21Out/111

Taking a Dump

Essa história é para morrer de rir. Espero sinceramente que não seja verdadeira, pois eu perderia o resto de fé que tenho na humanidade se isso realmente aconteceu:

Vince the PM burst into Rick's office like a blister. "Have you replied to ticket 178843 yet? No? Why not? How could you not! This is urgent! It's a failure at the customer site!"

Rick calmly checked the ticket manager. The ticket had arrived only 45 seconds ago, so no, he had not replied to the ticket yet. Rick calmly and silently read the ticket while Vince hyperventilated over his shoulder. The customer reported that the database client failed with the error "Segmentation Fault - Core Dumped".

"Someone probably screwed up a decimal point," Rick said. "It's always some little thing like that. I'll have them email me the core file so I can tell where the application crashed."

"We can't do that," Vince said.

"Sure we can," Rick said. In small words, he began to explain how adb and the symbol file would let him interpret the core dump, but Vince cut him off.

"Don't treat me like an idiot," Vince said. "I was reading cores before you were in diapers. But that core is a binary file."

There was a long gap in the conversation as Vince was sure his point was clear, and Rick was sure that Vince had no intention of actually making sense. With a huff, Vince warned, "We might get a virus from a binary file!"

Rick rolled his eyes and explained why this was an extremely unlikely possibility. For a half hour, each one of his attempts seemed only to make Vince dumber. "You cannot have them send us a binary file through email!"

"Fine," Rick said. "We can have them take a hex dump of the core file, and send that. I can convert it back and extract the data-"

"Data? We can't have them send us data!" Vince shrieked. He gave Rick a deep look of betrayal, as if to accuse Rick of wanting their network to get destroyed. "We could get-"

"-a virus?" Rick finished. "No, we won't."

Vince was having none of it. Rick, obviously, did not have the faintest idea how network security worked. "You really need to read more trade magazines," Vince said.

Rick focused instead on proposing new ideas. FTP? Virus. SFTP? HTTP Upload? Morse code? Virus. Overnight the file on a thumb drive? Too slow and still, virus.

"Look, we don't have time for all these foolish ideas," Vince said. "Just have them fax it to us. They can take that hex dump, print it out, and fax it to us. We'll use the interns to type it back in, and then you can load it up in the debugger, and then there's no way we could possibly catch a virus. Call the customer and tell them to do that."

The fact that Vince left the conversation with his skull still attached to his neck was either a testament to Rick's restraint or Vince's exceedingly high dodge bonus to armor class. Rick called the customer, and over the sound of his teeth grinding together, he explained the situation.

There was an extremely long pause at the other end of the line. Eventually the customer said, "You work for a group of morons."

"The customer is always right," Rick said, "but I'm still going to need you to fax that over."

They used enough paper to deforest a small South American country. The first few faxes didn't come across as fully legible. Then one of the interns dropped the stack of un-numbered pages. After getting the pages distributed the interns miskeyed a few characters. A careful page-by-page check found all of the mistakes, and Rick was finally able to use the debugger to analyze the core file. The problem was an unitialized variable.

Fonte: http://thedailywtf.com/Articles/Taking-a-Dump.aspx
Categorias: sandbox 1 Comentário
13Out/111

JavaScript para Brucutús

Os Ads do Lomadee estavam me torrando a paciência hoje: a tag <script> não deixava a página do post carregar. Saí de lá com o banco zoado, então pode ter algo relacionado. Solução? Remover o Lomadee? Não. Apelar para ignorância.

Troquei o equivalente a isto aqui:

<script src='urlTravada.js' type='text/javascript'></script>

Por isso aqui:

<div id="ad"></div>
<script type="text/javascript">
(function() {
  var alml = document.createElement('script');
  alml.type = 'text/javascript';
  alml.async = true;
  alml.src = 'urlTravada.js';
  var almlDiv = document.getElementById('ad');
  almlDiv.appendChild(alml);
})();
</script>

Moral da história: a página carrega e depois tenta iniciar o JavaScript. Se travar, travou apenas o Ad!

EDIT: Encontrei dois pequeno pormenores. Primeiro, o javascript do Lomadee usa o malígno "document.write" (que não funciona após o load da página). Fácil resolver: basta criar um novo "document.write". Segundo, isso quebrou o ad do Google, que também usa a mesma função. No fim, ambos estão com o mesmo lazy loading e o novo document.write é algo assim:

document.write = function(x) {
  var id = "";
  if (x.match(/contextAds/)) id = 'adLomadee';
  else id = 'adGoogle';
  document.getElementById(id).innerHTML += x;
};

Pode clicar nos dois! Funcionam como os originais!