Hoje veremos na prática como usar tuplas para ajudar a obter desempenho na linguagem C#. |
Tuplas
Uma tupla é uma estrutura de dados que tem um número específico e sequencial de elementos.
Um exemplo de uma tupla é uma estrutura de dados com três elementos (conhecido como uma tupla de 3 ou o triplo) que é usada para armazenar um identificador, como o nome da pessoa no primeiro elemento, um ano no segundo elemento e a renda da pessoa no terceiro elemento.
Assim uma tupla permite agregar valores, e o caso mais comum é permitir múltiplos valores de retorno de uma função sem precisar de parâmetros “out”.
Uma tupla pode ser formada por 1, 2, 3 ou mais itens, com os tipos de suas diferentes propriedades e seus respectivos valores sendo declarados entre parênteses.
Para saber mais sobre tuplas consulte os citados artigos nas referências.
Usando Tuplas
Neste artigo vamos usar os recursos das tuplas para realizar uma tarefa que exige desempenho.
A título de exercício prático vamos acessar e abrir um arquivo CSV chamado Vendas_2021.csv que possui aproximadamente 5 milhões de registros, e, vamos procurar fazer isso em um menor tempo possível usando a linguagem C#.
Vamos criar um projeto Console no .NET Core 5.0, criar uma tupla para receber os dados e a seguir vamos acessar, carregar e exibir alguns dados. Nosso objeto será abrir e carregar os dados na memória de forma rápida e depois exibir apenas 10 itens.
A estrutura do arquivo CSV usada é a seguinte:
Region,Country,Item Type,Sales
Channel,Order Priority,Order Date,Order ID,Ship Date,Units Sold,Unit
Price,Unit Cost,Total Revenue,Total Cost,Total Profit Australia and Oceania,Palau,Office Supplies,Online,H,3/6/2016,517073523,3/26/2016,2401,651.21,524.96,1563555.21,1260428.96,303126.25 Europe,Poland,Beverages,Online,L,4/18/2010,380507028,5/26/2010,9340,47.45,31.79,443183.00,296918.60,146264.40 North America,Canada,Cereal,Online,M,1/8/2015,504055583,1/31/2015,103,205.70,117.11,21187.10,12062.33,9124.77 Europe,Belarus,Snacks,Online,C,1/19/2014,954955518,2/27/2014,1414,152.58,97.44,215748.12,137780.16,77967.96 Middle East and North Africa,Oman,Cereal,Offline,H,4/26/2019,970755660,6/2/2019,7027,205.70,117.11,1445453.90,822931.97,622521.93 Sub-Saharan Africa,Burkina Faso,Office Supplies,Online,C,3/3/2012,309317338,4/5/2012,2729,651.21,524.96,1777152.09,1432615.84,344536.25 Europe,Montenegro,Personal Care,Online,H,11/24/2012,598814380,12/25/2012,1337,81.73,56.67,109273.01,75767.79,33505.22 .... |
O cabeçalho do arquivo possui 14 itens que podemos identificar pelo índice de 0 a 13.
Para isso vamos criar uma lista de tuplas com três itens do tipo string e vamos selecionar os itens : Region, Country e Total Profit ou seja os itens value[0], value[1] e value[13]
Assim usando a notação antiga das Tuplas vamos criar uma lista de tuplas chamada ListaVendas:
List<Tuple<string, string, string>> ListaVendas = new List<Tuple<string, string, string>>();
A seguir vamos verificar se o arquivo .csv na pasta c:\dados\csv existe, e, a seguir vamos abrir e ler o arquivo usando um StreamReader, lendo linha a linha do arquivo usando a função split() e o separador ',' para separar os itens da lista e a seguir preenchemos a lista de tuplas com os valores obtidos de cada linha lida:
if (File.Exists(@"C:\Dados\csv\Vendas_2021.csv")) { using (var reader = new StreamReader(@"C:\Dados\csv\Vendas_2021.csv")) { while (!reader.EndOfStream) { var linha = reader.ReadLine(); var valor = linha.Split(','); ListaVendas.Add(new Tuple<string, string, string>(valor[0], valor[1], valor[13])); } } } |
Após isso basta processar a lista realizando uma consulta LINQ onde vamos obter apenas os 10 primeiros itens da lista ordenados pelo valor do item Total Profit e exibir no console:
//PROCESSAMENTO var listaDezResultados = from vendas in ListaVendas.Skip(0).Take(10) orderby vendas.Item3 select vendas; //EXIBIÇÃO DOS DADOS foreach (var item in listaDezResultados) { Console.WriteLine($"{item.Item1} - {item.Item2} - {item.Item3}"); } stopwatch.Stop(); Console.WriteLine($"Tempo gasto {stopwatch.ElapsedMilliseconds / 1000}"); |
O código completo é visto abaixo:
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; namespace C_Desempenho1 static private void CarregarDados() //Carrega dados if (File.Exists(@"C:\Dados\csv\Vendas_2021.csv")) //PROCESSAMENTO
stopwatch.Stop(); |
Executando o projeto iremos obter o resultado a seguir:
Como vemos gastamos 6 segundos para carregar 5 milhões de registro na memória o que não é um tempo tão ruim.
"Nisto consiste o
amor: não em que nós tenhamos amado a Deus, mas em que ele nos amou e enviou o
seu Filho como propiciação pelos nossos pecados."
1 João 4:10
Referências:
C# - Operações com Collections
C# - List x Dictionary - Macoratti.net
C# - Usando um Dicionário para armazenar e ...
C# - Apresentando Hashtable - Macoratti.net
C# - Escolhendo a coleção correta para sua ...
C# - Programação Funcional - Exemplos -
C# - Coleções Imutáveis - Macoratti
C# 9.0 - Apresentando Records -
C# - Novidades da versão 7 - II -
C# - Os 10 Erros mais comuns dos iniciantes
C# - Apresentando Tuples
ASP .NET MVC 5 - Upload e leitura de arquivos CSV
C# - Otimizando o código
VB .NET - Convertendo CSV para DataTable
C# - Retornando múltiplos valores de um ...