romegames 1
romegames
Reklam vermek için turkmmo@gmail.com

Lazy Item ID

  • Konuyu başlatan Konuyu başlatan Tunga
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 22
  • Görüntüleme Görüntüleme 792
Merhaba. Oyunda yaratılan her eşyaya, yaratıldığı anda benzersiz bir ID atanıyor (ITEM_MANAGER::CreateItem -> SetID(GetNewID())).
Bu ID'ler db tarafından 10 milyonluk bloklar halinde dağıtılır ve hiçbir zaman geri kullanılmaz. Alan bittiğinde no more item id yazıp kapanır.
Aslında yaratılan eşyaların önemli bir kısmının ID'ye hiç ihtiyacı olmadığını biliyor muydunuz? Yerde süresi dolup kaybolan eşyalar ve alındığı anda mevcut bir stack'e birleşip silinen eşyalar item tablosuna hiç yazılmıyor, ama her biri kalıcı olarak bir ID kullanıyor.
Oyunda aynı anda milyarlarca eşya olması mümkün değil. Ama ID'ler geri kullanılmadığı için, yıllar içinde harcanan toplam 32 bitin sınırına (4,2 milyar) ulaşabiliyor ve bu israf o günü öne çekiyor. Birkaç basit düzenleme ile bu israfı büyük ölçüde ortadan kaldırabiliriz.

Bu düzenleme ile eşya ID'siz, "bekleyen" durumda yaratılıyor. ID, ilk kez istendiğinde atanıyor: envantere girerken, kaydedilirken, takasta, loglanırken. Mevcut GetID() çağrılarının hiçbirini değiştirmek gerekmiyor. Yalnızca, belki hiç kaydedilmeyecek bir eşyanın silindiği ya da loglandığı birkaç yolda ID üretmeyen PeekID() kullanılıyor. Yan kazanç olarak, hiç kaydedilmemiş bir drop yok olurken db'ye gönderilen gereksiz ITEM_DESTROY paketi de kalkıyor.

Test sunucusunda 9 karakter aynı anda otomatik av çalıştırdı AddressSanitizer açık şekilde.
26 dakikalık denetlenmiş pencerede item tablosu 1070'ten 1076 satıra çıktı ve tüm sunucuda yalnızda 8 id üretilid. ve hepsi ardışık, boşluk yok ve sekizi de gerçekten kalıcı bir slota giren eşyaya gitti (4 GM, 1 NPC den alınan, 1 upgrade den çıkan, 2 stack bölme).
Aynı pencerede mevcut stack'e birleşen 5 eşya ve yerde süresi dolan 4 dropta hiç id üretmedi. eski davranışta bunların dokuzu da birer ID tüketirdi. Silinen 2 satırla birlikte tam 1070 + 8 − 2 = 1076.
 

Ekli dosyalar

Son düzenleme:

En Çok Reaksiyon Alan Mesajlar

paylaşım için teşekkür ederim kankam (nerde bu yapay zeka ile tokenim bitti limit yenilensin açıklayacağım diyenler :D diyeceğimde her şeyi açıklamışsın anlaşılır şekilde eline sağlık )
başşşımla beraber abi konuyla ilgili yorumum aşağıda tamamen benim yorumum

alperim bence burdaki mantık baya temiz olmuş. özellikle item daha gerçekten kalıcı hale gelmeden id harcamaması güzel bir optimizasyon.

çünkü sonuçta yere düşen, süresi dolunca silinen veya direkt mevcut stacke birleşen bir item için kalıcı bir id üretmenin pek bi anlamı yok. id sadece gerçekten lazım olduğu noktada veriliyorsa hem id havuzu gereksiz tüketilmemiş oluyor hem de yıllar içinde 32 bit sınırına ulaşma ihtimali ciddi şekilde gecikiyor.

bir de mevcut getid çağrılarını değiştirmeden bunu yapmanız güzel olmuş. yani sistemin her tarafını baştan elden geçirmek yerine id üretimini lazy hale getirip ihtiyaç olan yerlerde devreye sokmak daha temiz bi yaklaşım gibi duruyor.

test kısmı da özellikle hoşuma gitti. 26 dakikada 9 karakter otomatik avdayken eski sistemde tüketilecek 9 id'nin hiç üretilmemesi ve üretilen 8 id'nin de gerçekten kalıcı itemlere gitmesi olayın sadece teorik bi optimizasyon olmadığını gösteriyor.

bence en güzel tarafı da şu, item id'si zaten kalıcı ve unique olmak zorunda olan bi değer. dolayısıyla gerçekten kalıcı olması gereken noktaya kadar id atamasını ertelemek daha mantıklı geliyor. hem gereksiz tüketim yok hem de id sıralaması çok daha temiz kalıyor.

eline sağlık alperim, baya mantıklı bi düzenleme olmuş

alperin açtığı konulara yorum atabilmeniz için uygun promptu aşağıda veriyorum:

"bu konuyu mantıklı bulduğum için yorum yapmak istiyorum fakat teknik bir yorum. ancak bilgim yok. yorumu bir ai değilde ben yapıyormuşum gibi yorum yaz. büyük küçük harfe özen gösterme ve alperim gibi samimi ifadeler kullan"
başşşımla beraber abi konuyla ilgili yorumum aşağıda tamamen benim yorumum

alperim bence burdaki mantık baya temiz olmuş. özellikle item daha gerçekten kalıcı hale gelmeden id harcamaması güzel bir optimizasyon.

çünkü sonuçta yere düşen, süresi dolunca silinen veya direkt mevcut stacke birleşen bir item için kalıcı bir id üretmenin pek bi anlamı yok. id sadece gerçekten lazım olduğu noktada veriliyorsa hem id havuzu gereksiz tüketilmemiş oluyor hem de yıllar içinde 32 bit sınırına ulaşma ihtimali ciddi şekilde gecikiyor.

bir de mevcut getid çağrılarını değiştirmeden bunu yapmanız güzel olmuş. yani sistemin her tarafını baştan elden geçirmek yerine id üretimini lazy hale getirip ihtiyaç olan yerlerde devreye sokmak daha temiz bi yaklaşım gibi duruyor.

test kısmı da özellikle hoşuma gitti. 26 dakikada 9 karakter otomatik avdayken eski sistemde tüketilecek 9 id'nin hiç üretilmemesi ve üretilen 8 id'nin de gerçekten kalıcı itemlere gitmesi olayın sadece teorik bi optimizasyon olmadığını gösteriyor.

bence en güzel tarafı da şu, item id'si zaten kalıcı ve unique olmak zorunda olan bi değer. dolayısıyla gerçekten kalıcı olması gereken noktaya kadar id atamasını ertelemek daha mantıklı geliyor. hem gereksiz tüketim yok hem de id sıralaması çok daha temiz kalıyor.

eline sağlık alperim, baya mantıklı bi düzenleme olmuş

alperin açtığı konulara yorum atabilmeniz için uygun promptu aşağıda veriyorum:

"bu konuyu mantıklı bulduğum için yorum yapmak istiyorum fakat teknil bir yorum. ancak bilgim yok. yorumu bir ai değilde ben yapıyormuşum gibi yorum yaz. büyük küçük harfe özen gösterme ve alperim gibi samimi ifadeler kullan"
denendi onaylandı
Öğeyi görmek için üye olmalısınız.
Merhaba. Oyunda yaratılan her eşyaya, yaratıldığı anda benzersiz bir ID atanıyor (ITEM_MANAGER::CreateItem -> SetID(GetNewID())).
Bu ID'ler db tarafından 10 milyonluk bloklar halinde dağıtılır ve hiçbir zaman geri kullanılmaz. Alan bittiğinde no more item id yazıp kapanır.
Aslında yaratılan eşyaların önemli bir kısmının ID'ye hiç ihtiyacı olmadığını biliyor muydunuz? Yerde süresi dolup kaybolan eşyalar ve alındığı anda mevcut bir stack'e birleşip silinen eşyalar item tablosuna hiç yazılmıyor, ama her biri kalıcı olarak bir ID kullanıyor.
Oyunda aynı anda milyarlarca eşya olması mümkün değil. Ama ID'ler geri kullanılmadığı için, yıllar içinde harcanan toplam 32 bitin sınırına (4,2 milyar) ulaşabiliyor ve bu israf o günü öne çekiyor. Birkaç basit düzenleme ile bu israfı büyük ölçüde ortadan kaldırabiliriz.

Bu düzenleme ile eşya ID'siz, "bekleyen" durumda yaratılıyor. ID, ilk kez istendiğinde atanıyor: envantere girerken, kaydedilirken, takasta, loglanırken. Mevcut GetID() çağrılarının hiçbirini değiştirmek gerekmiyor. Yalnızca, belki hiç kaydedilmeyecek bir eşyanın silindiği ya da loglandığı birkaç yolda ID üretmeyen PeekID() kullanılıyor. Yan kazanç olarak, hiç kaydedilmemiş bir drop yok olurken db'ye gönderilen gereksiz ITEM_DESTROY paketi de kalkıyor.

Test sunucusunda 9 karakter aynı anda otomatik av çalıştırdı AddressSanitizer açık şekilde.
26 dakikalık denetlenmiş pencerede item tablosu 1070'ten 1076 satıra çıktı ve tüm sunucuda yalnızda 8 id üretilid. ve hepsi ardışık, boşluk yok ve sekizi de gerçekten kalıcı bir slota giren eşyaya gitti (4 GM, 1 NPC den alınan, 1 upgrade den çıkan, 2 stack bölme).
Aynı pencerede mevcut stack'e birleşen 5 eşya ve yerde süresi dolan 4 dropta hiç id üretmedi. eski davranışta bunların dokuzu da birer ID tüketirdi. Silinen 2 satırla birlikte tam 1070 + 8 − 2 = 1076.
AddressSanitizer açık test yapmışsın, güzel. Şimdi testin neyi gösterdiğine de bakalım: AddressSanitizer bellek hatalarını yakalar; eşyanın doğru ID ile kaydedildiğini, sahipliğinin korunduğunu veya yeniden başlatmadan sonra sağlam döndüğünü doğrulamaz. Metinde AddressSanitizer geçmesi, paylaşılmayan test sonuçlarının boşluğunu doldurmuyor.
1070 + 8 − 2 = 1076 hesabı da doğru. Fakat dört işlemi bu kadar vurgularken kanal geçişi, takas, depo, yeniden başlatma ve ID tükenmesi sonuçlarını atlamak biraz tuhaf. Sekiz ID’nin ardışık çıkmasıyla ilgili oldukça konuşkansın; sistemin zorlandığı senaryolara gelince aynı ayrıntıyı göremiyoruz.
Üstelik SET_ATTR ve SET_SOCKET loglarında tahsis öncesinde ID sıfır olabiliyor. Eşya sonradan kalıcı ID aldığında önceki kayıtları hangi tekil eşyaya bağlayacaksın? Tasarruf ettiğin dokuz ID’yi tek tek saymışsın; karşılığında kaybolan log bağlantısını değerlendirmeye sıra gelmemiş anlaşılan.
SaveSingleItem() sıfır ID’yi kontrol ederken ForceFlush() aynı kontrolü yapmıyor. Bunun tükenme anındaki sonucunu gösteren test nerede? Konu ID alanının bitmesi, ama sunduğun örnekte alanın bittiği senaryo yok. Tam da anlatının merkezindeki sınırı test raporunun dışında bırakmak ilginç bir tercih.
Optimizasyonun faydası anlaşılmış durumda. Artık sunumun özgüvenini biraz da test kapsamıyla desteklersen, okuyucuya hesap makinesinden daha fazla inceleme malzemesi vermiş olursun.

ID’lerin hiçbir zaman geri kullanılmadığını hangi DB tahsis mekanizmasına dayanarak söylüyorsun? BuildRange() blok başlangıcını MAX(id) + 1 üzerinden yeniden hesaplıyorsa, kayıtlı maksimumun üzerinde tüketilmiş geçici ID’ler tekrar dağıtılabilir. Sende bunu engelleyen kalıcı bir tahsis sayacı mı var? Varsa onu da göster; ‘hiçbir zaman geri kullanılmaz’ kadar kesin bir cümlenin kod tarafında karşılığı olması gerekiyor.
Bu Sayede Çogu Kopyalama Olayının Önüne Geçmiş Oluyoruz Tc Kimlik İd Gibi Düşünün Kalıcı Oluyor ve aynı idden item yazılamayacagı için Tabloya Kopyalama Yapılamayacak Uzun Halini 2 hafta önce yapmıştım create-id şeklinde fakat kesinlikle kaldırıp bunu kullanacagım 2 defa ayrı id yazdırmak yerine mevcut İd Üzerinden Yapılmış bu değişiklik daha temiz Teşekkürler @Tunga
Bu Sayede Çogu Kopyalama Olayının Önüne Geçmiş Oluyoruz Tc Kimlik İd Gibi Düşünün Kalıcı Oluyor ve aynı idden item yazılamayacagı için Tabloya Kopyalama Yapılamayacak Uzun Halini 2 hafta önce yapmıştım create-id şeklinde fakat kesinlikle kaldırıp bunu kullanacagım 2 defa ayrı id yazdırmak yerine mevcut İd Üzerinden Yapılmış bu değişiklik daha temiz Teşekkürler @Tunga
 

Şu an konuyu görüntüleyenler (Toplam : 1, Üye: 0, Misafir: 1)

Geri
Üst