Refactor Önerileri

  • Konuyu açan Konuyu açan 0x23
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 10
  • Gösterim Gösterim 321

0x23

Çaylak Üye
Üye
Mesaj
15
Beğeni
22
Puan
10
Ticaret Puanı
0
selamlar, "Geliştirici Günlüğü" bölümünden gördüğüm kadarıyla metin2 developer arkadaşlar kodları bir tık yenileme eğiliminde, bu arkadaşlara bir kaç öneri ve kısaca bazı sebeplerini anlatacağım.

1: C Style Array to std::array
-> `std::array` c style arrayler ile aynı işlevleri görüp herhangi bir overhead içermez, memoryde contigous olarak sıralanır
-> parametreye argüman geçerken `array decay` uygulanmaz
-> c style arrayin sizeını alırken uzun syntaxtan ve olası hatalardan sizi member functionları sayesinde kurtarır(c++17'de gelen std::size fonksiyonu c style arraylerde kullanılabilir tabii)
-> random access iterator kategorisindedir, alakalı algoritmalar ile uyumludur
-> copy elisondan faydalanılabilir
-> "out of bound" kaynaklı undefined behavior durumlarına karşı "out_of_range" throw eder
-> tabii en önemlisi kodun Modern C++ ile uyumlu olması

Örnek:
C++:
Genişlet Daralt Kopyala
// c style
static const int lowerBox[] = { 50197, 50198, 50199 };
// std::array
static constexpr std::array<int, 3U> lowerBox{50197, 50198, 50199};

2: char array to std::string
-> en önemlisi gereksiz allocate durumudur, sourceda gördüğüm çoğu char array ihtiyaç olandan çok çok daha fazlasıyla oluşturulmuş
-> unutulmaması gereken bir nokta std::string bir containerdır ve heap üzerinde allocation yapar.
-> tuttuğunuz yazı çok büyük değilse derleyici SSO(small string optimization) yapacak ve heapda alan tahsis edilmeyecek bu sebeple özellikle size olarak küçük stringlerde tercih edilebilir
-> random access iterator kategorisindedir, alakalı algoritmalar ile uyumludur
-> member functionlarda cabası

3: std::bind optimization
-> alakalı yazıya paylaştığım bu konudan ulaşabilirsiniz;


4: Rule of Zero uyumu
-> kaynak yöneten bir classınız yoksa bırakın ctor ve assignment operatörlerinizi implicitly olarak derleyiciniz yazsın, siz yazmayın

5: C++ sürümü
-> bence minimum base artık C++17 hatta 20(belki) olmalıdır, 10+ sene önce release edilmiş sürümleri kullanmayın

6: string_view
-> özellikle parametrelerde tavsiye ederim, sizi gereksiz kopya maliyetinden kurtaracaktır
-> c style string(const char*) ve std::string ile uyumludur
-> verilen yazının başlangıç adresini ve sizeını tutmasından ötürü kullanımına dikkat edilmeli
-> uzun uzun yazmayayım ama ne kadar faydalı olsa da undefined behaviora sebep olabilecek durumlara dikkat edilmeli

tabii bunlar sadece 3-5 ufak trick, şimdiye kadar gördüklerime örnek verdim. C++ için ciddi bir eğitim ve tecrübe(tabii 5+ yıllık "developer" kişilerin bunlardan bihaber olduğu oluyor, siz herkesin peşinden koşmayın) gerekir, herkes C++ yazabilir ama bu dilde uzmanlık farklı bir konudur. burda bütün konuların olması mümkün değil metin2 iş dışında müsait oldukça sourcesine baktığım bir yazılım, bir şeyler gördükçe veya aklıma geldikçe düzenleme yapar veya yorum olarak eklerim.
 
Son düzenleme:
hocam yanlış anlamada diğer forumda da aynısını yapıyorsun bence hiçbir faydan yok tamamen boş yani yanlış anlama yinede. metin2 yi bilmiyorsun source yapısını bilmiyorsun sadece şunu şöyle yapın falan diyorsun. iyi forumlar.
 
hocam yanlış anlamada diğer forumda da aynısını yapıyorsun bence hiçbir faydan yok tamamen boş yani yanlış anlama yinede. metin2 yi bilmiyorsun source yapısını bilmiyorsun sadece şunu şöyle yapın falan diyorsun. iyi forumlar.
selamlar, düşüncelere saygım var elbet, siz berbat yazılmış pluginlere/eklentilere faydalı diyip bunlara faydasız bakıyorsanız bir şey diyemem, olta kullanmayı bilmeden balık tutamazsınız. benim herhangi bir hocam embeddeddan gelme değildi, temeli bilmeden üstüne çıktığınız ne kadar sağlıklı?

bunlara ek olarak;
konunun neresinde metin2 yapısıyla alakalı bir şey yazıyor?

metin2 yapısı dediğiniz client ile TCP/IP protokolü üzerinden haberleşen bir yazılım, bana “metin2 source uzmanı” varsa gösterebilir misiniz?

paylaşılan pluginlerin kaç tanesi “metin2 yapısı” bağımlı? tek yapılan paket ekleyip datayı işlemek

ben metin2de mi şöyle yapın demişim kod yazarken C++’a mı uyun demişim?
 
Son düzenleme:
selamlar, düşüncelere saygım var elbet, siz berbat yazılmış pluginlere/eklentilere faydalı diyip bunlara faydasız bakıyorsanız bir şey diyemem, olta kullanmayı bilmeden balık tutamazsınız. benim herhangi bir hocam embeddeddan gelme değildi, temeli bilmeden üstüne çıktığınız ne kadar sağlıklı?
burda herkes parasına bakıyor senin bu yazdıklarının hiçbirini yapmadan milyonlar kazanan arkadaşlar var (metin2 pvp açarak) yani bilgin var evet ama bence farklı oyun projelerine daha çok katkın olur. bu şey gibi derler ya burada harcanıyorsun öyle bence. tamamen şahsi fikrim yanlış anlaşılmasın lütfen.
 
burda herkes parasına bakıyor senin bu yazdıklarının hiçbirini yapmadan milyonlar kazanan arkadaşlar var (metin2 pvp açarak) yani bilgin var evet ama bence farklı oyun projelerine daha çok katkın olur. bu şey gibi derler ya burada harcanıyorsun öyle bence. tamamen şahsi fikrim yanlış anlaşılmasın lütfen.
yanlış anlayacağım bir şey yok, bilgi paylaştıkça güzeldir. benim burdan herhangi bir maddi manevi çıkarım yok, kazanana allah daha çok versin. daha önceleri belirttiğim gibi amaç bilgi paylaşımıdır.
 
Bir insan Architect ya da Senior seviyesinde C++ yazsın, metin2 kodlarına aşina olmadığı ya da oyunu bilmediği sürece sistem yazamaz, ancak optimizasyon yapabilir kısmen o da aktif oynanan oyunda nasıl bir reaksiyon gösterir bilemeyiz.

Bence topluluğa yardımcı olmak bildiklerinizi paylaşmak için buradaysanız, buranın da Metin2 forumu olduğunu aktif olarak düşünürsek aslında yapıyı iyice öğrenip Metin2 geliştiriciliği adına birşeyler paylaşmanız bence daha iyi olur.
 
Bir insan Architect ya da Senior seviyesinde C++ yazsın, metin2 kodlarına aşina olmadığı ya da oyunu bilmediği sürece sistem yazamaz, ancak optimizasyon yapabilir kısmen o da aktif oynanan oyunda nasıl bir reaksiyon gösterir bilemeyiz.

Bence topluluğa yardımcı olmak bildiklerinizi paylaşmak için buradaysanız, buranın da Metin2 forumu olduğunu aktif olarak düşünürsek aslında yapıyı iyice öğrenip Metin2 geliştiriciliği adına birşeyler paylaşmanız bence daha iyi olur.
bir arkadaş "cube" sistemi için ricada bulunmuştu, müsait olduğumda ara ara bakıyorum bitince release ediyor olacağım, buna ek olarak metin2nin ahım şahım bir yapısı yok ki neden herkes "yapı öğrenme" üzerine düşünüyor? server side zaten basit, bir backend engineer olmam açısından clientteki model renderdır odur budur pek ilgimi çekmiyor açıkçası. belki de server side bana çok basit gelmiştir işimden ötürü.
 
-> c style arrayin sizeını alırken uzun syntaxtan ve olası hatalardan sizi member functionları sayesinde kurtarır(c++17'de gelen std::size fonksiyonu c style arraylerde kullanılabilir tabii)
"_countof" neresi uzun geldi ya da size'a göre ne gibi bir ekstra hata yaratıyor?

-> "out of bound" kaynaklı undefined behavior durumlarına karşı "out_of_range" throw eder
".at" fonksiyonu için yazdığınız geçerli, c tarzı "[]" operatörü ile erişmeye çalıştığınızda yine patlayacak...

Örnek:
C++:
Genişlet Daralt Kopyala
// c style
static const int lowerBox[] = { 50197, 50198, 50199 };
// std::array
static constexpr std::array<int, 3U> lowerBox{50197, 50198, 50199};
"constexpr", "const" karşılığı değildir. C, compile time variable desteklemez, hatalı bir karşılaştırma.
"var[]" karşılığı "var[N] değildir, std::array flex size desteklemez. "var<T, N>" karşılığı, "T var[N]" dir.

-> en önemlisi gereksiz allocate durumudur, sourceda gördüğüm çoğu char array ihtiyaç olandan çok çok daha fazlasıyla oluşturulmuş

arrayler kullanılacak boyuta göre değil maksimum kapasiteye göre boyut aldığından genelleme olarak yanlış. kullanılan char arrayların tamamına yakını(muhtemelen tamamı ancak hatırlamadığım istisnalarda olabilir) stack üzerinden alan kullandığı için "gereksiz allocate" söz konusu değil.

-> unutulmaması gereken bir nokta std::string bir containerdır ve heap üzerinde allocation yapar.

-> tuttuğunuz yazı çok büyük değilse derleyici SSO(small string optimization) yapacak ve heapda alan tahsis edilmeyecek bu sebeple özellikle size olarak küçük stringlerde tercih edilebilir
yukarıdaki 2 maddenin bile birbiriyle alakası yok, kendi yazdığın şeyin altında kendi yazdığına ters bir şey ifade etmişsin...
Heap allocation sadece SSO çalışmadığı durumlarda gerçeklerşir.

3: std::bind optimization
-> alakalı yazıya paylaştığım bu konudan ulaşabilirsiniz;
diğer forumdada yazdığım üzere debug aşamasında ne ile karşılacağını bilmek yerine minimal performans tercih etmenin hiç bir mantığı yok.
lambda ile aynı yere çıkıyor, debug aşamasında tam kopya elde edilemeyeceği için problem yaratma ihtimali mevcut, yanlış kullanımda ownership'den kaynaklı olarak crash'e sebebiyet verme ihtimali mevcut, tüm paketler C tipi veriler kullanıyorken herhangi biri serializer kullanılmadan null terminator ile işlenen char arrayleri içeride string_view'e çevirmek yine problem yaratacaktır. string_view yerine string kopyasını işlemek her koşulda daha avantajlı olacaktır.

yukarıdada diğer kullanıcılar tarafından ifade edildiği gibi konunun metin2 ile alakası yok, C / C++ / C# daha uygun.

hayırlı forumlar.
 
"_countof" neresi uzun geldi ya da size'a göre ne gibi bir ekstra hata yaratıyor?


".at" fonksiyonu için yazdığınız geçerli, c tarzı "[]" operatörü ile erişmeye çalıştığınızda yine patlayacak...


"constexpr", "const" karşılığı değildir. C, compile time variable desteklemez, hatalı bir karşılaştırma.
"var[]" karşılığı "var[N] değildir, std::array flex size desteklemez. "var<T, N>" karşılığı, "T var[N]" dir.



arrayler kullanılacak boyuta göre değil maksimum kapasiteye göre boyut aldığından genelleme olarak yanlış. kullanılan char arrayların tamamına yakını(muhtemelen tamamı ancak hatırlamadığım istisnalarda olabilir) stack üzerinden alan kullandığı için "gereksiz allocate" söz konusu değil.




yukarıdaki 2 maddenin bile birbiriyle alakası yok, kendi yazdığın şeyin altında kendi yazdığına ters bir şey ifade etmişsin...
Heap allocation sadece SSO çalışmadığı durumlarda gerçeklerşir.


diğer forumdada yazdığım üzere debug aşamasında ne ile karşılacağını bilmek yerine minimal performans tercih etmenin hiç bir mantığı yok.

lambda ile aynı yere çıkıyor, debug aşamasında tam kopya elde edilemeyeceği için problem yaratma ihtimali mevcut, yanlış kullanımda ownership'den kaynaklı olarak crash'e sebebiyet verme ihtimali mevcut, tüm paketler C tipi veriler kullanıyorken herhangi biri serializer kullanılmadan null terminator ile işlenen char arrayleri içeride string_view'e çevirmek yine problem yaratacaktır. string_view yerine string kopyasını işlemek her koşulda daha avantajlı olacaktır.

yukarıdada diğer kullanıcılar tarafından ifade edildiği gibi konunun metin2 ile alakası yok, C / C++ / C# daha uygun.

hayırlı forumlar.
yine siz ve yine "yorum yapmak" için yazılmış bir yorum..

1-> _countof bir makro member function değil, bu bir alternatiftir overhead içermeyen bir yapı kullanmak varken neden C style array yazayım
2-> yazıda herhangi bir yerde "köşeli parantez operatörü exception throw eder" yazmıyor, containerların `.at` fonksiyonunun köşeli parantez operatöründen farkını bilmiyorsanız C++'a temelden başlamalısınız
3-> yazının herhangi bir yerinde "C" dili ile alakalı bir şey yazmıyor, "C Style" yazıyor, constexpr'ı görürsün bakarsın "bu neymiş" sonra dersin ki ben bu arrayi derleme zamanında zaten biliyorum neden runtimeda maliyet yaratayım? diye sorarsın bu soruları sormuyorsanız zaten sürekli aynı yerde sayarsınız
4-> memory hakkında fikrinizin olmadığını ezbere konuştuğunuzu düşünüyorum, auto storage bir variable tabii ki heap kadar maliyet yaratmaz, imkansız lakin sonuçta init edilmiştir. bana 100byte kullanılan size varken 8192 bytelık bir alan init etmenin bir mantığını açıklar mısınız?
5-> SSO'yu bilmediğinize bu yorumu yazmadan önce bir yerden baktığınıza eminim, yukardakinin tersi değil normal şartlarda heap kullanılır SSO'da ise heapde bir allocate oluşmaz bunu anlamıyorsanız bu yazıdan dolayı değildir farklı bir sorun aramak gerek
6-> siz bind kullanmaya devam edin, daha öncede açıkladım aynı şeyleri tekrar yazmayacağım
7-> string kopyalama maliyetinden kaçınmaktır amaç zaten, siz komiteden akıllısınız anladığım kadarıyla, kopya kullanmaya devam edin

sektörde bir kaç farklı C++ kodlama standartı var(MISRA, AUTOSAR vb.) var çalıştırdığınız sektöre göre, bu kuralların amacıda safe bir C++'dır, sektördeki herkes yarım akıllı rulelara uyuyoruz siz bir "metin2 developer" olarak bunlara "debug aşaması" falan diyip kendinizce "saçma" buluyorsunuz.. garip

beni yanlış anlamayın ama sizin yazdığınız kodları görüyor ve biliyoruz, bu zaten seviye belli eden bir şey(cpp'de static inline kullanımları, gereksiz heap allocationları, verbose code vb. hatırlamadığım onlarca durum). gerçekten bilgili biri olsanız ve sırf bu yorumları "haset" olmadan ve mantıklıca yapsanız saygı duyar üzerine tartışırdık hatta muhabbet bile ediyor olabilirdik. lütfen katkıda bulunacaksanız bulunun aksi taktirde altı boş yorumlar yapmayın, iyi forumlar.
 
1-> _countof bir makro member function değil, bu bir alternatiftir overhead içermeyen bir yapı kullanmak varken neden C style array yazayım

okumada ya da anlamada sıkıntımız var sanırım, fonksiyon olduğunu iddia eden olmadı. alıntıladığınız mesajı bir tekrar okuyun isterseniz ya da kısaca tekrar sorayım, _countof yazmanın std::size yazmaya göre neresi uzun geldi ve _countof, std::size'a göre ne gibi ekstra hata yaratır?

2-> yazıda herhangi bir yerde "köşeli parantez operatörü exception throw eder" yazmıyor, containerların `.at` fonksiyonunun köşeli parantez operatöründen farkını bilmiyorsanız C++'a temelden başlamalısınız
gerçekten farkını bilmiyorum, lütfen açıklayın.

3-> yazının herhangi bir yerinde "C" dili ile alakalı bir şey yazmıyor, "C Style" yazıyor, constexpr'ı görürsün bakarsın "bu neymiş" sonra dersin ki ben bu arrayi derleme zamanında zaten biliyorum neden runtimeda maliyet yaratayım? diye sorarsın bu soruları sormuyorsanız zaten sürekli aynı yerde sayarsınız
"C style" ya da Türkçe olarak "C tarzı" yazdığınızda dışarıdan anlaşılan C'de ki kullanım tarzı ve direkt olarak C diline bir atıf oluyor. amaç eski haliyle karşılaştırmaksa o "C++" sürümüne göre ya da o varyanta göre diye belirtilebilir, alakasız "C" katmak yerine.

4-> memory hakkında fikrinizin olmadığını ezbere konuştuğunuzu düşünüyorum, auto storage bir variable tabii ki heap kadar maliyet yaratmaz, imkansız lakin sonuçta init edilmiştir. bana 100byte kullanılan size varken 8192 bytelık bir alan init etmenin bir mantığını açıklar mısınız?
memory hakkında benim değilde sizin biraz probleminiz olduğu belli. modern c++'dan önce c++, c hatta mümkünse CS'e kadar geri gidip stack vs heap'den tekrar başlayın ondan sonra "auto storage" gibi anlamsız lifetime characteristic ifade eden sözcükleri yerinde kullanmayı belki öğrenip argüman sunarsınız.

keşke demagoji konusundaki yeteneklerinizi biraz programlama içinde kullansanız, alıntıladığınız ve cevap yazdığım mesajda char arraydan bahsederken konuyu byte'a taşımak çok komik oluyor. iyi niyetle yine char arraydan bahsettiğiniz ele alırsak "100" karakterlik alan zaten 15-16 karakteri geçeceği SSO'yu pas geçecek ve heap üzerinden tahsis edilecektir yani olay yine heap vs stack'e geliyor, alandan bağımsız olarak maliyetli olan şey bahsettiğiniz yöntem haline geliyor.

stack alanları direkt olarak fiziksel hafıza alanları kullanmaz ısrarla sandığınız ve bahsettiğiniz gibi bir "maliyet" oluşturmaz. stack üzerinde kullanılan sanal hafıza alanları sadece kullanılacağı zaman fiziksel hafızaya taşınır.

konudan o kadar uzaksınız ki "8192" yi gördüğünde kafanda canlanan tek şey her defasında scope içerisine girdiğinde arkaplanda "new(8192)" gibi bir işlem döndüğü ancak verdiğin örnekte bile 8192 karakterli bir char array bir std::string'e göre daha mantıklı bir seçenek, çünkü;

char buffer[8192]; tanımlandığında;
stack üzerinden kapasitesi öngörülebilir hızlı çalışan bir alan açacaktır, çünkü; stack alanları çalışma zamanlı allocation içermez. herhangi bir parçalama("fragmentation") kaynaklı ek performans etkileyici gereksinim bulundurmaz. bir yukarıda bahsettiğim üzere cache üzerinden aktarılır dolayısıyla daha hızlı çalışır.
std::string tanımlandığında;(+15/16 karakterden bahsediyorum)
direkt olarak dinamik alan/heap üzerinden işlem yapacaktır, dolayısıyla daha yavaş çalışacaktır. parçalama kaynaklı birden fazla defa internal'da re-allocation gerektirecektir. _countof gibi basit bir şey de bile overhead'dan söz ederken c++'da ki string yapısının temellerindeki overhead'i pas geçmek gerçekten akıl tutulması, başka bir şey söylemeye gerek yok.


konuda hiç bir yerde "saçma" gibi bir şey yazmadığım halde kendi kafanızın içinde ne kurarak yazıyorsunuz bilmiyorum ancak yazdığım her mesajı kişisel algılamak yerine herkesin daha fazla yarar sağlamasını amaçlıyorsanız bahsettiğim şeyleri düzeltmenizi ya da daha net açıklamanızı tavsiye ederim.
 
okumada ya da anlamada sıkıntımız var sanırım, fonksiyon olduğunu iddia eden olmadı. alıntıladığınız mesajı bir tekrar okuyun isterseniz ya da kısaca tekrar sorayım, _countof yazmanın std::size yazmaya göre neresi uzun geldi ve _countof, std::size'a göre ne gibi ekstra hata yaratır?


gerçekten farkını bilmiyorum, lütfen açıklayın.


"C style" ya da Türkçe olarak "C tarzı" yazdığınızda dışarıdan anlaşılan C'de ki kullanım tarzı ve direkt olarak C diline bir atıf oluyor. amaç eski haliyle karşılaştırmaksa o "C++" sürümüne göre ya da o varyanta göre diye belirtilebilir, alakasız "C" katmak yerine.


memory hakkında benim değilde sizin biraz probleminiz olduğu belli. modern c++'dan önce c++, c hatta mümkünse CS'e kadar geri gidip stack vs heap'den tekrar başlayın ondan sonra "auto storage" gibi anlamsız lifetime characteristic ifade eden sözcükleri yerinde kullanmayı belki öğrenip argüman sunarsınız.

keşke demagoji konusundaki yeteneklerinizi biraz programlama içinde kullansanız, alıntıladığınız ve cevap yazdığım mesajda char arraydan bahsederken konuyu byte'a taşımak çok komik oluyor. iyi niyetle yine char arraydan bahsettiğiniz ele alırsak "100" karakterlik alan zaten 15-16 karakteri geçeceği SSO'yu pas geçecek ve heap üzerinden tahsis edilecektir yani olay yine heap vs stack'e geliyor, alandan bağımsız olarak maliyetli olan şey bahsettiğiniz yöntem haline geliyor.

stack alanları direkt olarak fiziksel hafıza alanları kullanmaz ısrarla sandığınız ve bahsettiğiniz gibi bir "maliyet" oluşturmaz. stack üzerinde kullanılan sanal hafıza alanları sadece kullanılacağı zaman fiziksel hafızaya taşınır.

konudan o kadar uzaksınız ki "8192" yi gördüğünde kafanda canlanan tek şey her defasında scope içerisine girdiğinde arkaplanda "new(8192)" gibi bir işlem döndüğü ancak verdiğin örnekte bile 8192 karakterli bir char array bir std::string'e göre daha mantıklı bir seçenek, çünkü;

char buffer[8192]; tanımlandığında;
stack üzerinden kapasitesi öngörülebilir hızlı çalışan bir alan açacaktır, çünkü; stack alanları çalışma zamanlı allocation içermez. herhangi bir parçalama("fragmentation") kaynaklı ek performans etkileyici gereksinim bulundurmaz. bir yukarıda bahsettiğim üzere cache üzerinden aktarılır dolayısıyla daha hızlı çalışır.
std::string tanımlandığında;(+15/16 karakterden bahsediyorum)
direkt olarak dinamik alan/heap üzerinden işlem yapacaktır, dolayısıyla daha yavaş çalışacaktır. parçalama kaynaklı birden fazla defa internal'da re-allocation gerektirecektir. _countof gibi basit bir şey de bile overhead'dan söz ederken c++'da ki string yapısının temellerindeki overhead'i pas geçmek gerçekten akıl tutulması, başka bir şey söylemeye gerek yok.


konuda hiç bir yerde "saçma" gibi bir şey yazmadığım halde kendi kafanızın içinde ne kurarak yazıyorsunuz bilmiyorum ancak yazdığım her mesajı kişisel algılamak yerine herkesin daha fazla yarar sağlamasını amaçlıyorsanız bahsettiğim şeyleri düzeltmenizi ya da daha net açıklamanızı tavsiye ederim.
sizsiniz hocam kime ne anlatıyorum, hata bende
 
Geri
Üst