Discord sunucumuz açılmıştır, hepinizi bekleriz

https://discord.gg/43gGDQe6tS

Eklentileri Optimize Etmek

Moderatör: Moderatörler

Forum kuralları
[font size=20] DİKKAT [/font]

Silinmiş konu içerikleri hiçbir şekilde kontrol edlimemektedir. İndirdiğiniz dosyaların sorumluluğu tamamiyle size aittir.
Mutlaka indirdiğiniz dosyaları antivirüs ile taratınız.
Kullanıcı avatarı

Konu Sahibi
Colditz
Mesajlar: 2574
Kayıt: Çrş Ağu 23, 2017 9:17 pm

Eklentileri Optimize Etmek

Mesaj gönderen Colditz »

Hepinize merhaba arkadaşlar. Birçok yazar arkadaşımız eklentilerini kaba taslak yapıyor. Bunun içinde yazarlığa yeni başlamış arkadaşlar çoğunlukla bulunmakta. (Kimse üstüne alınmasın lütfen.) Daha doğrusu kimseden yardım istemediği veya araştırma yapmadığı için kendi bildiği gibi kodluyor. Burada birkaç optimize kodları hakkında anlatım yapacağım. Bu anlatım yabancı siteden alınmıştır.
Orjinalini okuyabilirsiniz; (Çeviri tıpa tıp aynısı değildir, bazıları doğru bazıları kendi eklediklerimdir)

https://wiki.alliedmods.net/Optimizing_ ... Scripting)


Giriş (Kısaltılmıştır) :
Çoğu kişi, yazılan eklenti için şunları varsaymaktadır:

* Önceden derlenmiş eklentileri daha optimize edemeyiz. Onlar zaten optimize edilmiş halde.
* Ayrıntılar, sadece "komut dosyası (sma)" olduğu için önemli değil

Öncelikle bunların hiçbiri doğru değil. Derleyici, aslında opitimize etme konusunda çok zayıftır ve eklentilerinizin hızını
ve verimliliğini birkaç kural göz önünde bulundurarak büyük ölçüde arttırabilirsiniz. Unutmayın ki;
Talimatları en aza indirmek, kod satırlarını en aza indirmekten daha iyidir.
( Yani kod satırı az olan eklentiler, çok olanlardan kesin daha hızlı çalışır diye bir şey yok.)

Derleyici Optimizasyonları :
Bu optimizasyonlar kodunuzun nasıl derleneceğini değiştirmekle ilgilidir. Sözdizimi aynı kalabilse bile,
sadece derleme süresini arttırmakla kalmaz, aynı zamanda eklentinin verimliliğini ve hızını da arttırırsınız.

* Her zaman sonuçları kayıt et :

Aşağıdaki örnek kodu inceleyiniz

Kod: Tümünü seç

if (get_user_team(player) == TEAM_T)
{
    //...code
} else if (get_user_team(player) == TEAM_CT) {
    //...code
} else if (get_user_team(player) == TEAM_SPECTATOR) {
    //...code
}
Bu, "sonuçlarınızı önbelleğe al" ın hafif bir örneğidir. Derleyici bu şekilde çalışacaktır.

Kod: Tümünü seç

CALL get_user_team
COMPARE+BRANCH
CALL get_user_team
COMPARE+BRANCH
CALL get_user_team
COMPARE+BRANCH
Sorunu fark ettiniz mi? Biz çağrıda get_user_team komutunu gereğinden fazla kez kullandık. Bunu böyle kayıt edebiliriz.

Kod: Tümünü seç

new team = get_user_team ( player ) 
if  ( team == TEAM_T ) 
{ 
    //...code 
}  else  ise  ( team == TEAM_CT )  { 
    //...code 
}  else  ise  ( team == TEAM_SPECTATOR )  { 
    //. ..code 
}
Şimdi derleyici bu şekilde çalışacaktır.

Kod: Tümünü seç

CALL get_user_team 
COMPARE + BRANCH 
COMPARE + BRANCH 
COMPARE + BRANCH
* If yerine switch kullan :
Eğer yapabiliyorsanız, if yerine switch komutunu kullanın. Bunun nedeni, derleyici aynı komutu defalarca kontrol ediyor.
Yukardaki örneği bu şekilde değiştirebiliriz.

Kod: Tümünü seç

new team = get_user_team(player)
switch (team)
{
  case TEAM_T:
     //code...
  case TEAM_CT:
     //code...
  case TEAM_SPECTATOR:
     //code...
}
Derleyici, case olarak adlandırlan yerleri kontrol edecektir. Derleyici bu şekilde çalışacaktır.

Kod: Tümünü seç

CALL get_user_team 
COMPARE 
COMPARE 
COMPARE
* Dizileri İndexlemeyin :
Eskiden yaygın bir hataydı. Artık o kadar kullanılmıyor fakat bunu da silmek istemedim. Sorun; dizileri yeniden diziye eklerek,
yer tasarrufu yapmaktır. Derleyicide yer tasarrufu yapıp bu şekilde eklentinizi kodlamayınız. Aşağıdaki koda bakalım;

Kod: Tümünü seç

new players[32], num, team
get_players(players, num, "h")
for (new i=0; i<num; i++)
{
   team = get_user_team(players[i])
   set_user_frags(players[i], 0)
}
Derleyici bu şekilde çalışacaktır.

Kod: Tümünü seç

:LOOP_BEGIN
   LOAD i
   LOAD players
   CALC
   LOAD players[i]
   CALL get_user_team
   LOAD i
   LOAD players
   CALC
   LOAD players[i]
   CALL set_user_frags
Ne olduğunu gördünüz mü? Derleyici indexi (players) önbelleğe almaz. Biz players komutunu defalarca kullandık.
Bu yüzden tekrar tekrar oyuncuları kontrol etti. Bunun yerine bu şekilde kullanmak daha iyi olacaktır;

Kod: Tümünü seç

new player
for (new i=0; i<num; i++)
{
   player = players[i]
   team = get_user_team(player)
   set_user_frags(player, 0)
}
Derleyici bu şekilde çalışacaktır.

Kod: Tümünü seç

:LOOP_BEGIN
   LOAD i
   LOAD players
   CALC
   LOAD players[i]
   STORE player
   CALL get_user_team
   LOAD player
   CALL set_user_frags
Büyük bir döngüde kodları bu şekilde büyük ölçüde azaltabilirsiniz.

* Küresel vs Yerel (Global vs Local) ve Döngülerdeki Değişkenler :
Bu konuyu kısa bir şekilde, anlayacağınız şekilde anlatacağım. Bazı şu anlık ilk başlayanlar için anlamsız yerleri sildim.
Döngüler içindeki dizileri bildirmekten kaçının. Aşağıdaki örneğe bir bakalım.

Kod: Tümünü seç

for (new i=0; i<num; i++)
{
   new message[255], name[32], player
   player = players[i]
   get_user_name(player, name, 31)
   format(message, 254, "Hello, %s", name)
}
Eğer 32 oyuncu varsa, bu döngü aslında bir satırda 32 kez sıfırlanacaktır ve tekrardan yazılacaktır. İyi değil!
Bunu dizenin ilk karakterini sıfırlayarak optimize edebiliriz. Aşağıdaki koda bir bakalım.

Kod: Tümünü seç

new message[255], name[32], player
for (new i=0; i<num; i++)
{
   player = players[i]
   name[0] = '^0'
   message[0] = '^0'
   get_user_name(player, name, 31)
   format(message, 254, "Hello, %s", name)
}
Bu komutlar çok fazla çalışma süresi yükünü büyük ölçüde azaltır.

* Statik vs Küresel (Static vs Global) :
new yerine static anahtar kelimesiyle bildirilen bir değişken, bir global yapıda olduğu gibi çalışır.
Yani yalnızca bir kez oluşturulur. Ancak değişken işlevi yereldir; Bu kodun hızını önemli ölçüde geliştirirken okunması daha kolay
olduğu anlamına gelir; Örnek:

Kod: Tümünü seç

stock SomeBigFunction()
{
   static gaben[255];
   format(gaben, "%L", LANG_SERVER, "STUFF");
}
NOT: Bir değişken statik olduğunda, işleviniz yinelemeli olarak veya aynı yığın içerisinde birden fazla kez
çağrılıyorsa, statik değişken kullanmamalısınız demektir. Yani değişkeni sadece salisede bir kere çalışan yığınlarda
veya herhangi bir yığında değişmeyen komut olması şartıyla kullanabilirsiniz. Bir örnek vereyim, bu örnekteki gibi kullanmayınız.

Kod: Tümünü seç

public PurposeLess_Ornek()
{
	static name[32];

	new players[32], inum;
	static Uid;
	get_players(players, inum);
	for(new i=0; i<inum; i++)
	{
		Uid = players[i];
		name[0] = '^0';

		get_user_name(Uid, name, charsmax(name));
		client_print_color(Uid, Uid, "Isminiz: %s", name);
	}
}
Herkesin ismini teker teker algılayacağı için bu değişkende statik değişken kullanmamalıyız.

* Sabit Değişkenler :
Değişken adından önce "const" anahtar sözcüğünü ekleyerek sabit değişkenini bildirebilirsiniz.

Kod: Tümünü seç

new const AMX_GABEN[] = "amx_gaben"
Bu, değişkenin değişmesini engeller. Aslında, değişkeni bir değere kilitlediniz.
Ek olarak, sabit değişkenler genellikle daha hızlı ve daha küçük kodla sonuçlanacak şekilde optimize edilir.

* Döngü Karşılaştırmaları (for komutu) :
Yaygın bir hata bu şekilde kullanımdır.

Kod: Tümünü seç

new string[256] = "something long"
for (new i=0; i<strlen(string); i++)
   //...code
Önceden benzer bir prensip yürütülür: önbellek sonuçları. Derleyici, döngü uzunluğunu, döngüdeki her yinelemede yeniden hesaplar.
Dize orta döngü değiştirilirse, bunun daha kötü etkileri olacaktır. Daha mantıklı bir yöntem.

Kod: Tümünü seç

new string[256] = "something long"
new len = strlen(string)
for (new i=0; i<len; i++)
   //...code
* Arama Tabloları :
Örnek olarak silah endekslerinin isimlere eleştirildiğini varsayalım.

Kod: Tümünü seç

if (weapon == CSW_AK47)
   copy(name, len, "weapon_ak47")
Amx Mod X içinde get_weapon_name komutu olduğu gerçeğini yok saymak verimsizdir.
Bu sonucu bir tabloda önceden yapabiliriz;

Kod: Tümünü seç

new g_WeaponNamesTable[TOTAL_WEAPONS][] = {
   //..0 to CSW_AK47-1
   "weapon_ak47",
   //..CSW_AK47+1 to TOTAL_WEAPONS-1
};
* Yerel Dizeler :
Bir sabit kodlu dizeyi eklentinizde çok kez kullanırsanız çok farklı kez görünecektir (kullanılacaktır).
Örnek;

Kod: Tümünü seç

set_cvar_num("amx_gaben", get_cvar_num("amx_gaben") + 1)
Bu komut gerçekten zarar vermez iken, eklentinizin boyutunu arttırır.
Benzer olarak, bu aynı sorun var.

Kod: Tümünü seç

#define AMX_GABEN "amx_gaben"
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)
Bu karışıklıktan kurtulmanın tek yolu, global değişken kullanmaktır.

Kod: Tümünü seç

new AMX_GABEN[] = "amx_gaben"
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)
Yine, gerekli olmasa da, bu eklentinin boyutunu hafızada ve diskte azaltacaktır. Zaten tanımlar kullanıyorsanız,
bu anahtarı kolay şekilde yapabilirsiniz.
Bunun değişmesini önlemek için, onu sürekli olarak bildirmek isteyebilirsiniz. (const kullanabilirsiniz)

Kod: Tümünü seç

new const AMX_GABEN[] = "amx_gaben"
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)
Şimdi mükemmel bir güvenli saklama yöntemi kullanılmış oldu.

Kullanabileceğiniz Daha Hızlı Komutlar :

* Cvar Pointers :
Cvar komutunu pointer ile kullanmak düzinelerce kat daha hızlı olan kritik bir optimizasyondur. Örneğin;

Kod: Tümünü seç

new g_enabled = register_cvar("csdm_enabled", "1")
//OR
new g_enabled = get_cvar_pointer("csdm_enabled")
 
stock SetCSDM(num)
   set_pcvar_num(g_enabled, num)
 
stock GetCSDM()
   return get_pcvar_num(g_enabled)
Tüm cvar komutları [set_cvar_string hariç] set_pcvar_* get_pcvar_* komutları ile eşleşir.
get_cvar_pointer veya register_cvar ile cvarları önbelleğe alabilirsiniz.

FormatEX :
format ile formatex komutu neredeyse aynı olarak çalışır. Fakat format komutu, geri kopyalama yeteneğine sahiptir.
Bir kaynak girdisi, çıktısı arabelleği ile aynı ise, formatex kullanılamaz. Örneğin; bunlar geçersiz;

Kod: Tümünü seç

new buffer[255]
formatex(buffer, charsmax(buffer), "%s", buffer);
formatex(buffer, charsmax(buffer), buffer);
formatex(buffer, charsmax(buffer), "%d %s", buffer[2]);
Bu komutlarda format kullanılmalıydı. Geri dönüş olmadığı sürede formatex kullanabilirsiniz. Genellikle format komutundan
daha hızlı çalışır.

FM_Touch (fakemeta.inc) | Ham_Touch (hamsandwich.inc) | register_touch(engine.inc):

Dokunanı algılama eklentisi yapacaksınız fakat hangisini kullanacağınızı bilmiyorsanız burada hangisinin daha hızlı
çalıştığını anlatacağım. Yabancı forum AMX Mod X Plugin Approver yani eklenti onaylayıcısı tarafından
denenmiştir.
[Kaynak:https://forums.alliedmods.net/showthread.php?t=213075]

register_touch aralarında en hızlı çalışan komuttur.
Eklenti yazarken register_touch kullanmanız eklentinizi biraz da olsa hızlandıracaktır.

Stock | Bool | Tagsız Komutlar [Hangisini kullanmalıyız?]
Eklentilerde bazen bir komutu veya bir düşünceyi tekrar tekrar kullanabiliyoruz. Bunun için kısayol tarzı bir şey yaptığımız da oluyor.
Peki bunlarda stock mu bool mu yoksa hiçbir tag kullanmayacak mıyız?

Öncelikle hiçbir eklentinizde stock kullanmayın. stock komutu çoğunlukla include yani kütüphanelerde kullanılıyor.
Eklentide kullanılması önerilmiyor.

; Kaynak : https://forums.alliedmods.net/showpost. ... stcount=13
You shouldn't be using "stock" in the .sma files. This tag is used only if there is a possibility that the function will not be used at all. Since this is your code and you added the function, you're probably going to use it as well, so remove the "stock" tag. Only use "stock" in include files where not all functions must be used in the code when included.

"bool" is **** self-explainatory. If the variable is tagged with "bool", then the return value of the function should also be "bool". Bools can be only true or false.
Bool ve tagsız komutlar için örneklere bakalım.
Oyuncular glow verme komutunu ele alabiliriz. 4 komutu kullanmak yerine bir komuta bağlayıp, o komutu kullanıyoruz.

Kod: Tümünü seç

rg_set_user_rendering(index, fx = kRenderFxNone, {Float,_}:color[3] = {0.0,0.0,0.0}, render = kRenderNormal, Float:amount = 0.0)
{
	set_entvar(index, var_renderfx, fx);
	set_entvar(index, var_rendercolor, color);
	set_entvar(index, var_rendermode, render);
	set_entvar(index, var_renderamt, amount);
}
Doğru veya yanlış şeklinde geri dönüş almamız gerekmediği için buna bir şey koymamıza gerek yoktur. Eklentide böyle kullanmanız
daha iyi olacaktır.

Kod: Tümünü seç

bool:is_user_stuck(index)
{
	static Float:origin[3];
	get_entvar(index, var_origin, origin);
	engfunc(EngFunc_TraceHull, origin,origin, IGNORE_MONSTERS, get_entvar(index, var_flags) & FL_DUCKING ? HULL_HEAD : HULL_HUMAN, 0, 0);
	return (get_tr2(0, TR_StartSolid)) ? true:false;
}
Burada oyuncunun gömülü olup olmadığını algıladığı için bize bir sonuç verecek ya doğru ya yanlış.
Bunu true false olarak sabitlemek için bool kullanmaniz daha iyi olacaktır. Gömülü ise true, değilse false.


Dosya yazılımı :
Hala yaygın olarak kullanılan bir hatadır. Amx Mod X ısrarla bu komutları kullanmayın demesine rağmen hala kullanılmakta.
read_file, write_file gibi komutlar yerine fopen, fgets, fputs, fclose gibi komutlar kullanılmalıdır.

+
Verdiğim siteden hangi komutun ne işe yaradığını ve nasıl çalıştığını öğrenebilirsiniz. Sorularınızı ve anlamadığınız yerleri sorabilirsiniz.
Umarım yardımcı olabilmişimdir. Sunucular için optimize edilmiş eklentiler yapmanız dileğiyle :)
Site: https://amxx-bg.info/api/
En son Colditz tarafından Pzt Tem 23, 2018 6:20 pm tarihinde düzenlendi, toplamda 2 kere düzenlendi.

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

ulyoS
Mesajlar: 4525
Kayıt: Cum Ara 16, 2016 2:14 pm
Konum: İzmir

Eklentileri Optimize Etmek

Mesaj gönderen ulyoS »

Müsait olunca okuyacağım.

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

Mustafa Kemal1
Mesajlar: 2059
Kayıt: Sal Oca 10, 2017 4:03 pm
Server Ip/DNS: csxx. Csduragi.com
Clan İsmi: kaoS GamınG
İletişim:

Eklentileri Optimize Etmek

Mesaj gönderen Mustafa Kemal1 »

Okuyan özet geçebilirmi :o

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

ulyoS
Mesajlar: 4525
Kayıt: Cum Ara 16, 2016 2:14 pm
Konum: İzmir

Eklentileri Optimize Etmek

Mesaj gönderen ulyoS »

Mustafa Kemal1 yazdı: Pzt Tem 23, 2018 6:22 pm Okuyan özet geçebilirmi :o
Sen kafana takma, ilgilendirmiyor :ugeek: daha doğru eklentiyi nasıl tam verim ile yormadan düzgün şekilde çalıştırırız bunu anlatmış.

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

Taha Demirbaş
Mesajlar: 10427
Kayıt: Cum Tem 08, 2016 10:05 pm
Konum: Türkiye
İletişim:

Eklentileri Optimize Etmek

Mesaj gönderen Taha Demirbaş »

Üşenmeyip yazıyorsun. Helal Tebrik ederim. :)
Zamanında komutları değişkenlere atayıp panelden geçirirdik Aklıma geldi de. :D

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

Konu Sahibi
Colditz
Mesajlar: 2574
Kayıt: Çrş Ağu 23, 2017 9:17 pm

Eklentileri Optimize Etmek

Mesaj gönderen Colditz »

@Taha Demirbaş
Daha bu hiçbir şey :) Araştırma yapıp ekleyeceğim çok şey var.
Konuyu defalarca güncellemek gerekecek :D Umarım yardım edersin.

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

Taha Demirbaş
Mesajlar: 10427
Kayıt: Cum Tem 08, 2016 10:05 pm
Konum: Türkiye
İletişim:

Eklentileri Optimize Etmek

Mesaj gönderen Taha Demirbaş »

Yorumdan Etiketle gördüğümde el atarım.

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

amad
Mesajlar: 1809
Kayıt: Cmt Nis 30, 2016 2:46 pm
Konum: Batman
Clan İsmi: Ke$`h | Gaming
İletişim:

Eklentileri Optimize Etmek

Mesaj gönderen amad »

Güzel paylaşım.

Link:
Linklerini gizle
Linki Kopyala

!berk!23
Yasaklı Üye
Yasaklı Üye
Mesajlar: 140
Kayıt: Pzr Tem 02, 2017 6:49 am

Eklentileri Optimize Etmek

Mesaj gönderen !berk!23 »

Zamanında bana bunlara bak dediğinde ingilizce olarak okumuştum o zaman el vermiyordu Türkçe kaynağa yeniler için çok yararlı olacaktır

Link:
Linklerini gizle
Linki Kopyala
Kullanıcı avatarı

Taha Demirbaş
Mesajlar: 10427
Kayıt: Cum Tem 08, 2016 10:05 pm
Konum: Türkiye
İletişim:

Eklentileri Optimize Etmek

Mesaj gönderen Taha Demirbaş »

Sana bir öneride bulunacağım. Textlerde ayrıntılı olsun anlaşılsın diye ayrıntılı olarak uzun uzun yazıyorsun fakat fazla uzun tutmamaya gayret et insanların %60 70'i Ayrıntıyı sevmiyor direkt sıkılabilirler. Bilgin olsun. Fazla ayrıntıdan uzak durursan önemlilerini ana yapıya alırsan emin ol daha fazla insana ulaşacaksın. Çünkü buradaki insanların çoğu tüketici(buldum indireyim hatta düzelttireyim) onların psikolojilerine uygun yapılmalı (Herkese söylüyorum.)

Link:
Linklerini gizle
Linki Kopyala
Kilitli