<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: João Batista Costa Oliveira</title>
    <description>The latest articles on DEV Community by João Batista Costa Oliveira (@jbcoliveira).</description>
    <link>https://dev.to/jbcoliveira</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F736226%2F83b6942e-09d8-42c1-a272-89fc2f23756f.jpeg</url>
      <title>DEV Community: João Batista Costa Oliveira</title>
      <link>https://dev.to/jbcoliveira</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jbcoliveira"/>
    <language>en</language>
    <item>
      <title>Como usar o cherry-pick no GIT</title>
      <dc:creator>João Batista Costa Oliveira</dc:creator>
      <pubDate>Thu, 09 Jun 2022 13:59:03 +0000</pubDate>
      <link>https://dev.to/jbcoliveira/como-usar-o-cherry-pick-no-git-o23</link>
      <guid>https://dev.to/jbcoliveira/como-usar-o-cherry-pick-no-git-o23</guid>
      <description>&lt;p&gt;Olá pessoal, tudo bem?&lt;/p&gt;

&lt;p&gt;Recentemente tive a necessidade de publicar no ambiente de produção algumas alterações, já aprovadas, que estavam em uma branch, porém outras alterações de outros desenvolvedores ainda estavam aguardando aprovação. Para ajudar a visualizar o cenário, temos as branches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;master&lt;/li&gt;
&lt;li&gt;homolog&lt;/li&gt;
&lt;li&gt;branch_joao&lt;/li&gt;
&lt;li&gt;branch_outro_dev&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DXQovXe5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19vuhmej9c0nf0jzfks5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DXQovXe5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19vuhmej9c0nf0jzfks5.png" alt="Cenário atual das branches" width="758" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como podem perceber, a aprovação ocorre em cima da branch &lt;code&gt;homolog&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Enfim, outro desenvolvedor e eu criamos &lt;code&gt;Pull Requests&lt;/code&gt; para &lt;code&gt;homolog&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Até então, somente a minha alteração foi aprovada e por conta do &lt;code&gt;Pull Request&lt;/code&gt; do colega, eu não poderia criar a &lt;code&gt;Pull Request&lt;/code&gt; de &lt;code&gt;homolog&lt;/code&gt; para &lt;code&gt;master&lt;/code&gt;, pois a alteração dele iria para produção.&lt;/p&gt;

&lt;p&gt;Pois bem, o &lt;code&gt;git&lt;/code&gt; tem o comando &lt;a href="https://git-scm.com/docs/git-cherry-pick"&gt;cherry-pick&lt;/a&gt;, que aplica alterações de acordo com &lt;code&gt;commits&lt;/code&gt; já existentes. Ou seja, cherry picking é o ato de escolher um commit de uma branch e aplicá-la em outra.&lt;/p&gt;

&lt;p&gt;Os comandos abaixo foram realizados no Git Bash.&lt;/p&gt;

&lt;p&gt;Obtem-se o &lt;code&gt;commit id&lt;/code&gt; desejado de &lt;code&gt;branch_joao&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 0b90d263bd15107c09955d735e8a671f537b4e4e
Author: João Oliveira 
Date:   Wed Jun 8 12:11:46 2022 -0300

Substituição de EmailHelper por MailKitHelper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obtem-se o código mais recente de todas as branches&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch --all     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cria-se uma nova branch baseada na &lt;code&gt;master&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b branch_joao_nova master      
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aplica-se a alteração desejada na branch. No meu caso, seria o id abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git cherry-pick 0b90d263bd15107c09955d735e8a671f537b4e4e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executa-se o &lt;code&gt;push&lt;/code&gt;com as alterações para a branch remota.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push -u origin branch_joao_nova
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para exemplificar, as branches ficaram assim. Suprimi homolog e branch_outro_dev para facilitar a leitura.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pebMOFbI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8cnkopsoq2gawl4c4ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pebMOFbI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8cnkopsoq2gawl4c4ys.png" alt="Nova branch e cherry pick" width="629" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois disso, cria-se um &lt;code&gt;Pull Request&lt;/code&gt; para a master e a situação foi contornada.&lt;/p&gt;

&lt;p&gt;Claro, neste exemplo não foi abordado nenhum conflito entre &lt;code&gt;commits&lt;/code&gt; ou outro tipo de situação que envolveria uma maior intervenção.&lt;/p&gt;

&lt;p&gt;Espero ter ajudado.&lt;/p&gt;

&lt;p&gt;Referências:&lt;br&gt;
&lt;a href="https://git-scm.com/docs/git-cherry-pick"&gt;https://git-scm.com/docs/git-cherry-pick&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.atlassian.com/git/tutorials/cherry-pick"&gt;https://www.atlassian.com/git/tutorials/cherry-pick&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>cherrypick</category>
    </item>
    <item>
      <title>Dicas para melhorar a performance em C# - parte 1</title>
      <dc:creator>João Batista Costa Oliveira</dc:creator>
      <pubDate>Tue, 07 Jun 2022 18:11:25 +0000</pubDate>
      <link>https://dev.to/jbcoliveira/dicas-para-melhorar-a-performance-em-c-parte-1-4hlj</link>
      <guid>https://dev.to/jbcoliveira/dicas-para-melhorar-a-performance-em-c-parte-1-4hlj</guid>
      <description>&lt;p&gt;Neste post, vamos comentar sobre algumas melhorias que podemos fazer para obter uma melhor performance do código produzido.&lt;/p&gt;

&lt;p&gt;Algumas dicas podem se tornar irrelevantes se a quantidade de dados processada for pequena. Então, não precisa sair alterando seus códigos somente para obter uma melhora que é impercepível para o usuário.&lt;/p&gt;

&lt;p&gt;Muitos desenvolvedores tem a preocupação de otimizar seus códigos, obtendo uma melhor performance em tempo de execução. Isso melhora a experiência de usuário, pois ele não ficará esperando tempo desnecessário aguardando uma resposta da aplicação. Além disso, economiza recursos de sistema.&lt;/p&gt;

&lt;p&gt;Alguns exemplos foram encontrados em revisões de código que fiz e sugeri ou eu mesmo apliquei as melhorias.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como medir?
&lt;/h2&gt;

&lt;p&gt;Para a medição da performance de código utilizaremos uma classe chamada &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=net-6.0"&gt;StopWatch&lt;/a&gt;, pois é muito mais precisa do que a classe &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.datetime?view=net-6.0"&gt;DateTime&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Diagnostics;

var stopWatch = new Stopwatch();
stopWatch.Start();

//Código para teste

stopWatch.Stop();

Console.WriteLine("Tempo utilizado: {0}ms", stopWatch.ElapsedMilliseconds);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ordem de condições no IF
&lt;/h3&gt;

&lt;p&gt;Muitas vezes, não prestamos atenção na ordem de condições no IF. No exemplo abaixo (não é dos melhores, eu sei), temos duas condições AcessaBanco() e isActive.&lt;/p&gt;

&lt;p&gt;Não sabemos quanto tempo AcessaBanco() vai demorar para ser executado e qual será sua resposta: true ou false, mas temos isActive já fornecido.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void Exemplo1(int id, bool isActive)
{
    if (AcessaBanco(id) || isActive)
    {
        Console.WriteLine("entrou");
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como temos uma condição OU &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#conditional-logical-or-operator-"&gt;||&lt;/a&gt;, o código será executado quando uma das condições for verdadeira. Se o lado esquerdo for verdadeiro, logo, o lado não é executado.&lt;/p&gt;

&lt;p&gt;Podemos mudar, então, para:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static void Exemplo1(int id, bool isActive)
{
    if (isActive || AcessaBanco(id))
    {
        Console.WriteLine("entrou");
    }

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Operadores &amp;amp;&amp;amp; e || vs &amp;amp; e |
&lt;/h3&gt;

&lt;p&gt;Os operadores &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#logical-and-operator-"&gt;&amp;amp;&lt;/a&gt; e &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#logical-or-operator-"&gt;|&lt;/a&gt; avaliarão os dois lados do operando independente do resultado de cada um. &lt;/p&gt;

&lt;p&gt;Para começarmos, vamos definir os métodos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static bool ValidacaoA()
{
    Console.WriteLine("Validacao A");
    return true;
}

public static bool ValidacaoB()
{
    Console.WriteLine("Validacao B");
    return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos ao teste.&lt;br&gt;
No exemplo abaixo, os dois métodos abaixo serão executados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(ValidacaoA() | ValidacaoB())
{
    Console.WriteLine("Testou os dois");
}

//Saída
//Validacao A
//Validacao B
//Testou os dois
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Já os operadores &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#conditional-logical-and-operator-"&gt;&amp;amp;&amp;amp;&lt;/a&gt; e &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#conditional-logical-or-operator-"&gt;||&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bool a = false &amp;amp; PerformanceTeste.ValidacaoB();
Console.WriteLine(a);

//Saída
//Validacao B
//False

bool b = true &amp;amp; PerformanceTeste.ValidacaoB();
Console.WriteLine(b);

//Saída
//Validacao B
//True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logo, se for possível, utilize os operandos &amp;amp;&amp;amp; e ||.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparar Strings
&lt;/h3&gt;

&lt;p&gt;Para este teste, foi criada uma lista de 500.000 objetos. Cada objeto da lista contém duas propriedades do tipo string (chamei de MyProperty1 e MyProperty2). Foram geradas para cada propriedade uma string &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.random?view=net-6.0"&gt;aleatória&lt;/a&gt; de 50 posições.&lt;/p&gt;

&lt;p&gt;No primeiro teste, foi utilizada a comparação &lt;strong&gt;PALAVRA1&lt;/strong&gt; == &lt;strong&gt;PALAVRA2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ao executar o teste conforme o código abaixo, obteve-se o resultado de &lt;strong&gt;80ms&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static bool Exemplo3(string str1, string str2)
{
    return str1.ToLower() == str2.ToLower();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao utilizar &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.string.compare?view=net-6.0"&gt;string.Compare&lt;/a&gt;, obteve o resultado de &lt;strong&gt;15ms&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static bool Exemplo3Alterado(string str1, string str2)
{
    return string.Compare(str1,str2,true) == 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou seja, apenas com essa mudança obteve-se um melhora de 90%. Nada mal.&lt;/p&gt;

&lt;h3&gt;
  
  
  List e ArrayList
&lt;/h3&gt;

&lt;p&gt;O exemplo a seguir trata das diferenças de performance entre List e ArrayList.&lt;/p&gt;

&lt;p&gt;Vamos deixar bem simples e utilizar apenas List e ArrayList com inteiros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const int _tamanho = 100000;
public static void Exemplo4()
{
    ArrayList arrayList = new ArrayList();
    for (int i = 0; i &amp;lt; _tamanho; i++)
    {
        arrayList.Add(i);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obteve-se um resultado de 31ms.&lt;/p&gt;

&lt;p&gt;Ao utilizarmos o List com um tamanho predefinido (uma forma de obter maior performance) teremos o seguinte: 0ms (!!)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const int _tamanho = 100000;
public static void Exemplo4Alterado()
{
    List&amp;lt;int&amp;gt; intlist = new List&amp;lt;int&amp;gt;(_tamanho);
    for (int i = 0; i &amp;lt; _tamanho; i++)
    {
        intlist.Add(i);
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por enquanto é isso, em breve teremos a parte 2.&lt;br&gt;
Abraços.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>Como "fatiar" ("chunk") Lists ou Enumerable em pedaços menores em C#</title>
      <dc:creator>João Batista Costa Oliveira</dc:creator>
      <pubDate>Tue, 07 Jun 2022 13:48:36 +0000</pubDate>
      <link>https://dev.to/jbcoliveira/como-fatiar-ou-chunk-lists-ou-enumerable-em-pedacos-menores-em-c-3el8</link>
      <guid>https://dev.to/jbcoliveira/como-fatiar-ou-chunk-lists-ou-enumerable-em-pedacos-menores-em-c-3el8</guid>
      <description>&lt;p&gt;Hoje vou compartilhar um pequeno trecho de código em C# que permite que você "fatie"  ou (crie um "chunk" de) uma lista em n listas menores utilizando Linq. &lt;/p&gt;

&lt;p&gt;O código "fatia" um  Enumerable em C# em um tamanho especificado, se a lista dada não puder ser dividida uniformemente, o pedaço final conterá os elementos restantes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Collections.Generic;
using System.Linq;

public static class ListHelper{
  public static List&amp;lt;List&amp;lt;T&amp;gt;&amp;gt; ChunkList&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; data, int size)
  {
    return data
      .Select((x, i) =&amp;gt; new { Index = i, Value = x })
      .GroupBy(x =&amp;gt; x.Index / size)
      .Select(x =&amp;gt; x.Select(v =&amp;gt; v.Value).ToList())
      .ToList();
  }
}

//Exemplo
List&amp;lt;int&amp;gt; numList = new List&amp;lt;int&amp;gt; { 1, 2, 3, 4, 5 }; 
ListHelper.ChunkList(numList, 3); // { {1, 2, 3}, {4, 5} }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>csharp</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
