using System.Collections.Generic;
using System.Diagnostics;
public class TransactionDTO
public int TransactionId { get; set; }
public int PortfolioId { get; set; }
public decimal Amount { get; set; }
public DateTime Date { get; set; }
public class PortfolioDTO
public int PortfolioId { get; set; }
public string PortfolioName { get; set; }
public class PortPriceSouceDTO
public int PortfolioId { get; set; }
public IList<String> EquitySources { get; set; }
public IList<String> FixedIncomeSources { get; set; }
public IList<String> FxRateSources { get; set; }
public static void Main(string[] args)
int portfolio_num = 2000;
List<TransactionDTO> transactions = new List<TransactionDTO>();
for (int i = 0; i < 1000000; i++)
transactions.Add(new TransactionDTO
PortfolioId = i % portfolio_num,
Amount = new Random().Next(1000, 10000),
List<PortfolioDTO> portfolios = new List<PortfolioDTO>();
for (int i = 0; i < portfolio_num; i++)
portfolios.Add(new PortfolioDTO
PortfolioName = "Portfolio " + i
List<PortPriceSouceDTO> portPriceSources = new List<PortPriceSouceDTO>();
for (int i = 0; i < portfolio_num; i++)
portPriceSources.Add(new PortPriceSouceDTO
EquitySources = ["SET", "MARKETMAKER"],
FixedIncomeSources = ["TBMA", "BOT_REPO", "BLOOMBERG"],
FxRateSources = ["REUTERS", "BLOOMBERG", "BOT_FX"]
Stopwatch stopwatch = new Stopwatch();
ProcessTransactionWithOnlyList(transactions, portfolios, portPriceSources);
Console.WriteLine($"ProcessUseOnlyList Time: {stopwatch.ElapsedMilliseconds} ms");
IDictionary<int, PortfolioDTO> portDic = portfolios.ToDictionary(x => x.PortfolioId, x => x);
IDictionary<int, PortPriceSouceDTO> portPriceSourceDic = portPriceSources.ToDictionary(x => x.PortfolioId, x => x);
ProcessTransactionWithListAndDic(transactions, portDic, portPriceSourceDic);
Console.WriteLine($"ProcessTransactionWithListAndDic Time: {stopwatch.ElapsedMilliseconds} ms");
public static void ProcessTransactionWithOnlyList(IList<TransactionDTO> pTransactions, IList<PortfolioDTO> pPortfolios, IList<PortPriceSouceDTO> pPortPriceSources)
foreach (var transaction in pTransactions)
var portfolio = pPortfolios.FirstOrDefault(p => p.PortfolioId == transaction.PortfolioId);
var portPriceSource = pPortPriceSources.FirstOrDefault(p => p.PortfolioId == transaction.PortfolioId);
if (portPriceSource != null)
public static void ProcessTransactionWithListAndDic(IList<TransactionDTO> pTransactions, IDictionary<int, PortfolioDTO> pPortDic, IDictionary<int, PortPriceSouceDTO> pPortPriceSourceDic)
foreach (var transaction in pTransactions)
var portfolio = pPortDic.ContainsKey(transaction.PortfolioId) ? pPortDic[transaction.PortfolioId] : null;
var portPriceSource = pPortPriceSourceDic.ContainsKey(transaction.PortfolioId) ? pPortPriceSourceDic[transaction.PortfolioId] : null;
if (portPriceSource != null)