) çok hızlı şeyler yapmak için 100 öğeden oluşan grup başına farklı thread/çekirdeklere birden fazla istek göndermek.
Ancak tüm bunları yapmadan önce, toplu işlemlerin kullanıldığı read through the limitations (100 öğe, işlem başına 1 bölüm, ...).
Güncelleme:
burada işlemleri kullanamazsınız diğer bazı ipuçları beri. Tablo depolamayı kullanırken performansı iyileştirmek için this MSDN thread'a bir göz atın.
private static void SequentialInserts(CloudTableClient client)
{
var context = client.GetDataServiceContext();
Trace.WriteLine("Starting sequential inserts.");
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 1000; i++)
{
Trace.WriteLine(String.Format("Adding item {0}. Thread ID: {1}", i, Thread.CurrentThread.ManagedThreadId));
context.AddObject(TABLENAME, new MyEntity()
{
Date = DateTime.UtcNow,
PartitionKey = "Test",
RowKey = Guid.NewGuid().ToString(),
Text = String.Format("Item {0} - {1}", i, Guid.NewGuid().ToString())
});
context.SaveChanges();
}
stopwatch.Stop();
Trace.WriteLine("Done in: " + stopwatch.Elapsed.ToString());
}
Yani, bu ilk çalıştırdığınızda aşağıdaki çıktıyı almak: 1000 öğeler eklemek için en fazla 3 dakika sürer
Starting sequential inserts.
Adding item 0. Thread ID: 10
Adding item 1. Thread ID: 10
..
Adding item 999. Thread ID: 10
Done in: 00:03:39.9675521
Sana farkı göstermek için bazı kodlar yazdım.
Starting sequential inserts.
Adding item 0. Thread ID: 10
Adding item 1. Thread ID: 10
..
Adding item 999. Thread ID: 10
Done in: 00:00:18.9342480
:
<system.net>
<settings>
<servicePointManager expect100Continue="false" useNagleAlgorithm="false"/>
</settings>
<connectionManagement>
<add address = "*" maxconnection = "48" />
</connectionManagement>
</system.net>
Ve uygulamayı çalıştırdıktan sonra
yine sonuç alırsınız: Şimdi, MSDN forumunda ipuçlarını temel app.config değiştirdi (çekirdek CPU sayısı * maxconnection 12 olmalı)
3 dakikadan 18 saniyeye kadar. Ne fark! Ama daha iyisini yapabiliriz. İşte bazı kod, bir bölümleyici kullanarak tüm öğeleri ekler edilir (eklemeler paralel olur):
private static void ParallelInserts(CloudTableClient client)
{
Trace.WriteLine("Starting parallel inserts.");
var stopwatch = new Stopwatch();
stopwatch.Start();
var partitioner = Partitioner.Create(0, 1000, 10);
var options = new ParallelOptions { MaxDegreeOfParallelism = 8 };
Parallel.ForEach(partitioner, options, range =>
{
var context = client.GetDataServiceContext();
for (int i = range.Item1; i < range.Item2; i++)
{
Trace.WriteLine(String.Format("Adding item {0}. Thread ID: {1}", i, Thread.CurrentThread.ManagedThreadId));
context.AddObject(TABLENAME, new MyEntity()
{
Date = DateTime.UtcNow,
PartitionKey = "Test",
RowKey = Guid.NewGuid().ToString(),
Text = String.Format("Item {0} - {1}", i, Guid.NewGuid().ToString())
});
context.SaveChanges();
}
});
stopwatch.Stop();
Trace.WriteLine("Done in: " + stopwatch.Elapsed.ToString());
}
Ve sonuç:
Starting parallel inserts.
Adding item 0. Thread ID: 10
Adding item 10. Thread ID: 18
Adding item 999. Thread ID: 16
..
Done in: 00:00:04.6041978
Voila, biz 18s düştü ve şimdi bile düştü 3m39s gelen 4s.
Bu mantığın tümünü bir döngüde CreateTableIfNotExist() ile çağırıyor musunuz? ya da sadece bir döngü içinde Add/SaveChanges()? CreateTableIfNotExist() ucuz bir çağrı değildir ve gerekmiyorsa atlamak istersiniz – Igorek
Bu kod her istek için çalışır. Sen her zaman CreateTableIfNotExist çağırmak için pahalı pahalı haklısın. Bunu kaldırmaya çalışacağım ve sadece tablo hata yoksa. – gabba