Pesquisa

sábado, 16 de maio de 2009

Melhoria de Performance - Boas práticas

Melhor arquitetura do software, melhor modelagem, melhor servidor, prever número de acessos… muitas coisas influenciam na performance de uma aplicação asp.net.

Além de tentar melhorar esses “pilhares” da performance, é necessário rever questões simples de desenvolvimento. Muitas vezes, simples detalhes de lógica de desenvolvimento é o ponto mais crítico e crucial para acabar com desempenho de qualquer aplicação.

DEV411 - ASP.NET:  Best Practices For Performance

10 Tips for Writing High-Performance Web Applications

Nos dois links acima existem pontos bem interessantes relacionados a performance e desenvolvimento.

Acredito que dois pontos bem relevantes são:

  • A utilização de vários “ResultSet” para uma pesquisa que retorne um SqlDataReader, assim, fazendo menos transações no banco de dados, e tratando o retorno na aplicação.
  • A paginação em banco de dados para retornar somente o volume necessário de dados, assim, melhorando o desempenho, já que não será processado informaçõe desnecessárias.
  • A utilização do cache.
  • A utilização do cast explicito no databinding de controles.

domingo, 3 de maio de 2009

Remover Acentos

Para remover os acentos de Strings aplica-se o seguinte método:

public static string RemoveAcento(this string texto)
{
texto = texto.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();

foreach (char c in texto.ToCharArray())
{
if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
{
sb.Append(c);
}
}
return sb.ToString();
}


Créditos: R0drigo da Silva Araujo

Web Trend Map

Mapa publicado anualmente pela iA Inc mapeia os 333 domínios mais influentes da web e as 111 pessoas mais influentes na Internet. Cada domínio é avaliado com base no tráfego, as receitas, a idade e a empresa que a possui.

Créditos: o UAU nosso de cada dia

Formatar DateTime

Existem várias maneiras de apresentar em String uma variável do tipo DateTime.
Basicamente existem duas coisas que influenciam nisso.
CultureInfo
Fornece as informações referentes à uma cultura específica (localidade). Essas informações influenciam diretamente em datas, caracteres, calendários, etc.
Mais informações sobre CultureInfo.
Exemplos:
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
Formatando a String
Customizando a formatação do método ToString() do objeto DateTime é possível fazer inúmeras combinações para a visulalização da data/hora.
Exemplos:
DateTime now = new DateTime(2006, 9, 07, 15, 06, 01, 08, DateTimeKind.Local);
now.ToString();      //"09/27/2006 15:06:01"

//Year
now.ToString("%y");   //"6"
now.ToString("yy");   //"06"
now.ToString("yyy");  //"2006"
now.ToString("yyyy"); //"2006"

//Month
now.ToString("%M");    //"9"
now.ToString("MM");    //"09"
now.ToString("MMM");   //"Sep"
now.ToString("MMMM");  //"September"

//Day
now.ToString("%d");    //"7"
now.ToString("dd");    //"07"
now.ToString("ddd");   //"Thu"
now.ToString("dddd");  //"Thursday"

//Hour
now.ToString("%h");    //"3"
now.ToString("hh");    //"03"
now.ToString("hhh");   //"03"
now.ToString("hhhh");  //"03"
now.ToString("%H");    //"15"
now.ToString("HH");    //"15"
now.ToString("HHH");   //"15"
now.ToString("HHHH");  //"15"

//Minutes
now.ToString("%m");    //"3"
now.ToString("mm");    //"03"
now.ToString("mmm");   //"03"
now.ToString("mmmm");  //"03"

//Seconds
now.ToString("%s");    //"1"
now.ToString("ss");    //"01"
now.ToString("sss");   //"01"
now.ToString("ssss");  //"01"

//Milliseconds
now.ToString("%f");    //"0"
now.ToString("ff");    //"00"
now.ToString("fff");   //"008"
now.ToString("ffff");  //"0080"
now.ToString("%F");    //""
now.ToString("FF");    //""
now.ToString("FFF");   //"008"
now.ToString("FFFF");  //"008"

//Kind
now.ToString("%K");    //"-07:00"
now.ToString("KK");    //"-07:00-07:00"
now.ToString("KKK");   //"-07:00-07:00-07:00"
now.ToString("KKKK");  //"-07:00-07:00-07:00-07:00"
// Note: The multiple K were just read as multiple instances of the
// single K

DateTime unspecified = new DateTime(now.Ticks, DateTimeKind.Unspecified);
unspecified.ToString("%K");   //""

DateTime utc = new DateTime(now.Ticks, DateTimeKind.Utc);
utc.ToString("%K");           //"Z"

//TimeZone
now.ToString("%z");     //"-7"
now.ToString("zz");     //"-07"
now.ToString("zzz");    //"-07:00"
now.ToString("zzzz");   //"-07:00"

//Other
now.ToString("%g");    //"A.D."
now.ToString("gg");    //"A.D."
now.ToString("ggg");   //"A.D."
now.ToString("gggg");  //"A.D."

now.ToString("%t");    //"P"
now.ToString("tt");    //"PM"
now.ToString("ttt");   //"PM"
now.ToString("tttt");  //"PM" 
Ou então utilizando as formatações padrões já existentes.
Exemplos:
now.ToString("d");  // "09/27/2006"
now.ToString("D");  // "Tuesday, 27 September 2006"
now.ToString("G");  // "09/27/2006 14:15:39"
Abaixo estão os padrões existentes.
Ano Mês Dia:
d = "MM/dd/yyyy"
D = "dddd, dd MMMM yyyy"
M or m = "MMMM dd"
Y or y = "yyyy MMMM"
Hora:
t = "HH:mm"
T = "HH:mm:ss"
Ano Mês Dia e Hora sem fusos horários:
f = "dddd, dd MMMM yyyy HH:mm"
F = "dddd, dd MMMM yyyy HH:mm:ss"
g = "MM/dd/yyyy HH:mm"
G = "MM/dd/yyyy HH:mm:ss"
Ano Mês Dia e Hora com fusos horários:
o = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK"
R or r = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"
s = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"
u = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'"
U = "dddd, dd MMMM yyyy HH:mm:ss"
A utilização de outro caractér acarretará uma Exception.
Créditos: Kathy Kam

sábado, 2 de maio de 2009

Formatar String

Utilizando o String.Format (veja também Formatar dinheiro R$)
"{<argument index>[,<alignment>][:<formatString><zeros>]}"
argument index:
Valor que apresenta a ordem da String
alignment (opcional):
Representa o número mínimo de caracteres da String
Em valores positivos, o argumento será justificada à direita e se o tamanho não é suficientemente longo, a espaço vai ser preenchido com espaços à esquerda.
Em valores negativos, o argumento será justificada à esquerda e se a corda não é suficientemente longo, o espaço vai ser preenchido com espaços à direita.
String.Format("{0,-10}", "apple");      //"apple     "
String.Format("{0,10}", "apple");       //"     apple"
formatString(opcional):
Este código representa o formato.
Formacação de número, disponível aqui.
Formacação de data, disponível aqui.
Formatação de enum, disponível aqui.
Formatação de número, disponível aqui.
int pos = 10;
int neg = -10;
int bigpos = 123456;
int bigneg = -123456;
int zero = 0;
string strInt = "120ab";
String.Format("{0:00000}", pos);      //"00010"
String.Format("{0:00000}", neg);      //"-00010"
String.Format("{0:00000}", bigpos);   //"123456"
String.Format("{0:00000}", bigneg);   //"-123456"
String.Format("{0:00000}", zero);     //"00000"
String.Format("{0:00000}", strInt);   //"120ab"
String.Format("{0:#####}", pos);      //"10"
String.Format("{0:#####}", neg);      //"-10"
String.Format("{0:#####}", bigpos);   //"123456"
String.Format("{0:#####}", bigneg);   //"-123456"
String.Format("{0:#####}", zero);     //""
String.Format("{0:#####}", strInt);   //"120ab"
String.Format("{0:X00000}", pos);      //"A"
String.Format("{0:X00000}", neg);      //"FFFFFFF6"
String.Format("{0:X#####}", pos);      //"X10"
String.Format("{0:X#####}", neg);      //"-X10"
Zeros (opcional):
Ele tem um significado diferente dependendo do que você usar a formatação do número.
int neg = -10;
int pos = 10;
// C or c (Currency): quantidade de casas decimais que aparecerá.
String.Format("{0:C4}", pos);      //"$10.0000"
String.Format("{0:C4}", neg);      //"($10.0000)"

// D or d (Decimal): quantidade de zeros à esquerda.
String.Format("{0:D4}", pos);      //"0010"
String.Format("{0:D4}", neg);      //"-0010"

// E or e (Exponential): quantidade de casas decimais que aparecerá.
String.Format("{0:E4}", pos);      //"1.0000E+001"
String.Format("{0:E4}", neg);      //"-1.0000E+001"

// F or f (Fixed-point): quantidade de casas decimais que aparecerá.
String.Format("{0:F4}", pos);      //"10.0000"
String.Format("{0:F4}", neg);      //"-10.0000"

// G or g (General): não faz nada
String.Format("{0:G4}", pos);      //"10"
String.Format("{0:G4}", neg);      //"-10"

// N or n (Number): quantidade de casas decimais que aparecerá.
String.Format("{0:N4}", pos);      //"10.0000"
String.Format("{0:N4}", neg);      //"-10.0000"

// P or p (Percent): quantidade de casas decimais que aparecerá.
String.Format("{0:P4}", pos);      //"1,000.0000%"
String.Format("{0:P4}", neg);      //"-1,000.0000%"

// R or r (Round-Trip): representa uma formatação inválida, e "joga" uma FormatException 
String.Format("{0:R4}", pos);      //FormatException thrown
String.Format("{0:R4}", neg);      //FormatException thrown

// X or x (Hex): quantidade de zeros à esquerda
String.Format("{0:X4}", pos);      //"000A"
String.Format("{0:X4}", neg);      //"FFFFFFF6"

// Nada: representa uma formatação inválida, porém, não "joga" uma FormatException 
String.Format("{0:4}", pos));      //"4"
String.Format("{0:4}", neg));      //"-4"
Créditos: Kathy Kam

domingo, 26 de abril de 2009

Melhorando a Performance e Escalabilidade de Aplicações .NET

Este documento da MSDN patterns & practices aborda várias questões de modelagem de banco de dados, arquitetura de software, camadas de negócio e acesso a dados, melhoria de desempenho, etc...

Improving .NET Application Performance and Scalability

Google - AJAX APIs Playground

Ferramenta extremamente útil para quem quer aprender a programar APIs do google.

O Ajax APIs Playground tem vários de exemplos do que pode ser feito com diferentes APIs, incluindo as do buscador, Maps, Earth, Calendar e Blogger.

A página tem três módulos: o primeiro, à esquerda, exibe os exemplos divididos em categorias; o segundo, no alto e à direita, mostra o código, e pode ser editado; e o terceiro, que ocupa a parte inferior, permite executar o código e ver o resultado. É possível salvar e exportar os dados.

a

Confira!

Ultimo dia do mês

Como descobrir o último dia no mês:
int ano = 2009;
int mes = 09;
int ultimoDiaDoMes = DateTime.DaysInMonth(ano,mes);

quinta-feira, 26 de março de 2009

Acessando código fonte do .NET Framework

Com o lançamento do Visual Studio 2008 e do .NET Framework 3.5 a Microsoft anunciou publicamente a liberação de acesso ao código fonte para leitura durante o debug mediante concordância com os termos de licenciamento. Vale lembrar que as versões Express (gratuitas) não terão acesso a essa funcionalidade.
Para ter o acesso você precisa rodar um hotfix que vai atualizar o Visual Studio 2008 de forma a suportar os downloads dos arquivos de Symbols com as informações necessários ao debug.
As classes abaixo estão disponíveis para utilização:

  1. .NET Base Class Libraries (including System, System.CodeDom, System.Collections, System.ComponentModel, System.Diagnostics, System.Drawing, System.Globalization, System.IO, System.Net, System.Reflection, System.Runtime, System.Security, System.Text, System.Threading, etc).
  2. ASP.NET (System.Web, System.Web.Extensions)
  3. Windows Forms (System.Windows.Forms)
  4. Windows Presentation Foundation (System.Windows)
  5. ADO.NET and XML (System.Data and System.Xml)

Siga os procedimentos abaixo para configuração:

  1. Instale o hotfix Visual Studio 2008 QFE
    https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=10443&wa=wsignin1.0
    Pode ocorrer um erro durante a instalação desse fix caso você tenha uma versão anterior (beta 2) instalado. Para resolver basta colocar o dvd do Visual Studio 2008 no drive.
  2. Configurando o Visual Studio 2008
    Inicie o VS2008 e vá em Tools > Options > Debugging
    a) Para iniciar o debug do código fonte desmarque a opção: Enable Just My Code (Managed only)
    b) Certifique de marcar a opção: Enabled source server support



  3. Configurando arquivo Symbols
    O Visual Studio 2008 vai automaticamente baixar os arquivos necessários para o debug do código fonte. Para isso você precisa seguir os passos de configuração abaixo:

    a) Adicione a referência para : http://referencesource.microsoft.com/symbols
    b) Defina a pasta que será salvo os arquivos de debug.
    c) Marque a opção: "Search the above loactions only when symbols are loaded manualy" (Download manual)
    d) Você pode optar também por não marcar a opção citada na letra "c" que o Visual Studio vai fazer download automático, porém pode demorar a depender da conexão internet (+- 50 MB). (Recomendado após os primeiros testes)
    Configurando Symbol

  4. Iniciando depuração do código
    Chegou o tão esperado momento de colocar em prática os conhecimentos e explorar o .NET por dentro.

    a) Coloque seu break point dentro do seu código.
    b) Rode o projeto.
    c) Localize a janela Call Stack ou chame com o atalho: CTRL + ALT + C .
    d) Selecione na janela Call Stack as referências e depois Load Symbols conforme figura 03 (download manual).
    e) Durante o processo de debug o Visual Studio vai salvar os arquivos de Symbols na pasta cache. Janela Call Stack

Definida as configurações você já pode colocar em prática e avaliar por exemplo a implementação do método DataBind de um GridView. Confira nas duas figuras seguintes:
Parte 1 - Colocando Break Point no DataBind()

GridView / DataBind

Parte 2 - Navegando pelo método DataBind() usando "F11"

DataBind

Parte 3 - Avaliando a implementação do DataBind do GridView diretamente no código fonte.

Dentro do método DataBind.

Com esse processo os desenvolvedores mais curiosos agora podem finalmente enxergar em tempo real o que está acontecendo nas chamadas de métodos internos do .NET.
Referências:
- . NET Framework Library Source Code now available
- Configuring Visual Studio to Debug .NET Framework Source Code

Créditos: Ramon Durães - http://www.linhadecodigo.com.br/Artigo.aspx?id=1655

sexta-feira, 13 de fevereiro de 2009

Passagem de parâmetros

Em C#, os parâmetros podem ser passador por valor ou por referência. Passando parâmetros por referência permite que o método altere o valor do parâmetro passado e as mudanças persistem após a passagem do método.

Passando uma variavel do tipo Valor para um método significa passar uma cópia da variável para o método. Quaisquer alterações ao parâmetro que ocorrem no interior do método não tem nenhum efeito sobre os dados originais armazenadas na variável. Se você quiser que o chamado método para alterar o valor do parâmetro, você tem que passá-la por referência, usando a palavra ref.

Passagem de parâmetro tipo Valor, por Valor:

// PassingParams1.cs 
using System;
class PassingValByVal
{
static void SquareIt(int x)
// O parametro x é chamado por Valor.
// Alterações no x não afetarão o valor original do myInt.
{
x *= x;
Console.WriteLine("O valor antes de chamar o método: {0}", x);
}
public static void Main()
{
int myInt = 5;
Console.WriteLine("O valor antes de chamar o método: {0}",
myInt);
SquareIt(myInt); // Passing myInt by value.
Console.WriteLine("O valor após chamar o método: {0}",
myInt);
}
}
Saida:
O valor antes de chamar o método: 5
O valor dentro do método: 25
O valor após chamar o método: 5
Explicação: A variável myInt sendo um tipo de valor contém seus dados (o valor 5). Quando SquareIt é chamado, o conteúdo do myInt é copiado para o parâmetro x que é multiplicado por ele mesmo dentro do método. No Main porém, o valor de myInt é o mesmo, antes e depois de chamar o método SquareIt. Logo, a mudança que ocorre no interior do método afeta somente a variável local x.

Passagem de parâmetro tipo Valor, por Referencia:

// PassingParams2.cs 
using System;
class PassingValByRef
{
static void SquareIt(ref int x)
// O parametro x é passado por referencia.
// Alterações no x afetarão a conteudo do myInt.
{
x *= x;
Console.WriteLine("O valor dentro do método: {0}", x);
}
public static void Main()
{
int myInt = 5;
Console.WriteLine("valor antes de chamar o método: {0}",
myInt);
SquareIt(ref myInt); // Passing myInt by reference.
Console.WriteLine("O valor após chamar o método: {0}",
myInt);
}
}
Saida:
O valor antes de chamar o método: 5
O valor dentro do método: 25
O valor após chamar o método: 25
Neste exemplo, não é o conteudo de myInt que é passado, mas sim, uma referência à myInt. O parâmetro x não é um int, mas sim uma referência a um int (neste caso, uma referência à myInt). Portanto, quando x é multiplicado por ele mesmo dentro do método, o que realmente é multiplicado é o conteudo da variavel refenciada por x, no caso, myInt.

Passando de parâmetros do tipo Referência, por Valor:

// PassingParams4.cs 
// Passing an array to a method without the ref keyword.
using System;
class PassingRefByVal
{
static void Change(int[] arr)
{
arr[0]=888; // Essa alteraçao ocorre na variavel original.
arr = new int[5] {-3, -1, -2, -3, -4}; // Alteração somente local.
Console.WriteLine("Dentro do método, o primeiro elemento é: {0}", arr[0]);
}

public static void Main()
{
int[] myArray = {1,4,5};
Console.WriteLine("Dentro do Main, antes de chamr o método, o primeiro elemento é: {0}", myArray [0]);
Change(myArray);
Console.WriteLine("Dentro do Main, depois de chamr o método, o primeiro elemento é: {0}", myArray [0]);
}
}
Saida:
Dentro do Main, antes de chamr o método, o primeiro elemento é: 1
Dentro do método, o primeiro elemento é: -3
Dentro do Main, depois de chamr o método, o primeiro elemento é: 888
No exemplo anterior, a matriz, myArray que é um tipo Referência, ela é passada para o método sem o parâmetro ref. Nesse caso, uma cópia da referência, o que aponta para myArray é passada para o método. O resultado mostra que é possível que o método para alterar o conteúdo de um elemento matriz (de 1 a 888). No entanto, alocando uma nova parte de memória usando o operador new no interior do método Change faz com que a variável arr referência uma nova matriz. Assim, quaisquer alterações depois disso que não irá afetar a matriz original, myArray ,que foi criada no interior Main. Na verdade, duas matrizes são criadas neste exemplo, dentro do Main e uma no interior do método Change.

Passando de parâmetros do tipo Referência, por Referencia:


// PassingParams5.cs 
// Passando um array para um método utilizando ref.
// Compare com o exemplo anterior.
using System;
class PassingRefByRef
{
static void Change(ref int[] arr)
{
// As duas operaçoes alterarão o a variavel original.
arr[0]=888;
arr = new int[5] {-3, -1, -2, -3, -4};
Console.WriteLine("Dentro do método, o primeiro elemento é: {0}", arr[0]);
}

public static void Main()
{
int[] myArray = {1,4,5};
Console.WriteLine("Dentro principal, antes de chamar o método, o primeiro elemento é o seguinte: {0}", myArray [0]);
Change(ref myArray);
Console.WriteLine("Dentro principal, depois de chamar o método, o primeiro elemento é: {0}", myArray [0]);
}
}
Saida:
Dentro principal, antes de chamar o método, o primeiro elemento é o seguinte: 1
Dentro do método, o primeiro elemento é: -3
Dentro principal, depois de chamar o método, o primeiro elemento é: -3
Todas as mudanças que ocorrem no interior do método afeta a variavel original. De fato, o array original é reatribuídos usando o operador new. Assim, depois de chamar o método Change, qualquer referência a um dos ponto do myArray persistirá o valor alterado no método.

Mais informações:

http://msdn.microsoft.com/en-us/library/0f66670z(vs.71).aspx

http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx

http://msdn.microsoft.com/en-us/library/490f96s2.aspx

Créditos: Rodrigo Araujo, Márcio Martins, eu.