Jump to content
Forumu Destekleyenlere Katılın ×
Paticik Forumları
2000 lerden beri faal olan, çok şukela bir paylaşım platformuyuz. Hoşgeldiniz.

C# List 'de bir performans sorusu


Pluton

Öne çıkan mesajlar

Selamlar, kendimce C# 'da birşeyler karalıyorum. Şimdi bir programım var ve bunda elemanlar oturum açmak zorundalar.

Ben bu oturumlara bir IP limit getirerek tek IP'den belli bir oturum açılmasını istiyorum. Bunun için şöyle bir yol izliyorum.

private static List IpPool = new List();
private static IpAdress ClientIP;

public Enable() {
//burada eleman oturum açtığı zaman işlemler var
if(IpPool.Count(c => c == ClientIP) >= 5) {
//Burada adamı direkt disconnect edeceğiz.
}
IpPool.add(ClientIP);
}

public Disconnect() {
//Burada oturum kapatıldığı zaman işlemler var
IpPool.remove(ClientIP);
}

Sistem çalışıyor ancak c# 'da orta seviye olduğum için performans olarak daha sağlıklısını yapabilir miyim ?
Link to comment
Sosyal ağlarda paylaş


// yeni gelen IPAddress, yani sanıyorum ClientIP
var ip = ...;

var pool = new Dictionary<IPAddress, List<IPAddress>>();

List<IPAddress> sessions = null;

if(dict.TryGetValue(ip, out sessions))
{
// bu ip'den gelen başka sessionlar da varmış

if(sessions.Count >= 5)
{
// ve sayısı 5'ten fazlaymış

// (*) 4. session'dan sonrakilerin tümünü al
var fazlalik = sessions.Skip(4).ToList();

// (**) aşağıdakilerde Remove çağırmak yerine direkt 4. elemana kadar olan kısmı alarak yeni liste oluştur
pool[ip] = sessions.Take(4).ToList();

// (***) diğer session'ları artık disconnect edebilriz
foreach(var session in fazlalik)
Disconnect(session);
}
}
else
{
// başka session yokmuş, hem listeyi oluşturalım
// hem de sessions objesine atayalım ki aşağıda kullanabilelim
sessions = new List<IPAddress>();
pool[ip] = sessions;
}

sessions.Add(ip);



Bi dictionary'ye TryGetValue ya da [] operatörü ile erişmenin complexity'si O(1), aynı şekilde bi listenin eleman sayısına erişmek de O(1). O yüzden burdaki tek bottleneck (***) ile işaretlediğim kısımdaki Disconnect çağıran kısım.geri kalanı hep ufak tefek işlemler.

Yalnız bu collection'lar thread safe değil, o yüzden özellikle de 1'den fazla client aynı anda geldiğinde beklendiği gibi davranmaması muhtemel. Dictionary yerine ConcurrentDictionary, List yerine BlockingCollection kullanılabilir ama (*) ve (**) ile işaretli kısımlar olduğu sürece içerdeki BlockingCollection'un da pek bi anlamı kalmayacak. Neyse artık, ona da eğer client connect/disconnect olurken sıkıntılar yaşarsan (session'ların görünmemesi gibi) bakarız sdf
Link to comment
Sosyal ağlarda paylaş

Orada zaten foreach'e sokmama gerek yok ya. Direkt olarak break yapıp sonlandırırım. Hata mesajı verdirmeye verelim.

O zaman sanıyorum daha çok işe yarar

----

Birde abi benim anlamadığım kaçırdığım nokta şurası. "pool" diye oluşturduğumuz Dictionary 'e eklemeden başka hiçbirşey yapmıyoruz biz. Yani herhangi bir kontrol v.b birşey yok sadece ekleme var görebildiğim kadarıyla.

"sessions" 'a ekleme yapıp ondan sorguluyoruz. O zaman "pool" zımbırtısını neden oluşturup içine ipleri ekliyoruz.
Link to comment
Sosyal ağlarda paylaş

  • 3 hafta sonra ...
List sınıfı yeterince performanslıdır(c# pointerları kullanarak iyi algoritmayla listeler sana sadece fonksiyonu çağırmak kalır).Ama ben daha fazlasını istiyorum dersen memcache, redis gibi distirbuted da çalışabilen Key-Value store lazım. Böylece tüm sunucuların(eğer birden fazlaysa) birbirlerinden haberdar olarak (threadsafe de) İp adreslerini ramde key olarak tutarak tam istediğine ulaşabilirsin.
Link to comment
Sosyal ağlarda paylaş

×
×
  • Yeni Oluştur...