# Concepts - Optimization Tips

- **İngilizce aslı:** https://wiki.facepunch.com/gmod/optimizationTips
- **Çeviri tarihi:** 2026-08-05

## En İyi Zamanı Bilmek

Optimizasyon performansı artırabilir, ancak kodun anlaşılmasını ve bakımını da zorlaştırabilir. Doğruluk ve okunabilirlik genellikle önce gelmelidir.

Optimize etmeden önce şunu sorun:

- Kod tamamlanmış ve düzgün çalışıyor mu?
- Bu kodun bir önemi var mı?
- Profilleme bunu bir engelle mi tanımladı?
- Geliştirme, okunabilirlik kaybını haklı çıkarıyor mu?
- Diğer geliştiricilerin daha sonra bu kodu değiştirmeleri gerekecek mi?

Bir kere çalıştırılan kodda birkaç mikrosaniye tasarruf etmek nadiren işe yarar. `Tick`, `Think`, `HUDPaint`, görüntüleme kancaları veya büyük bir döngü, saniyede birçok kez meydana geldiği için önemli olabilir.

### Optimize Etmeden Önce Önlem Alın

Sadece görünüşüne dayanarak kodun yavaş olduğunu düşünmeyin.

[SysTime](https://gmod.tr/wiki/Global.SysTime) LuaJIT derlemesi, mevcut sunucu yükü ve Lua ile motor arasındaki aramalar sonucu etkileyebileceği için bir benchmark'ı birden fazla kez çalıştırın.

Küçük referans değerleri yararlıdır, ancak iyileştirmeler nihayetinde kodun kullanıldığı gerçek sistemde ölçülmelidir.

```lua
local iterations = 100000
local startedAt = SysTime()
local result = 0
for i = 1, iterations do
	result = result + i
end
local elapsed = SysTime() - startedAt

-- Sonuç kullanımı, karşılaştırmalı çalışmanın kullanılmamış olarak değerlendirilmesini engeller.
print( "Result:", result )
print( "Total time:", elapsed )
print( "Average time:", elapsed / iterations )
```

## En Önemli İpuçları

### Yerel Değişkenleri Kullanın

Lua değişkenleri küreseldir. `local` Lokal değişkenler mevcut kapsam veya işlevle sınırlıdır. Lua VM'nin erişimi için daha ucuz olmakla birlikte eklentiler arasındaki tesadüfi çatışmaları önlüyorlar.

Yerel değerler function registers'da depolanır veya yükseltme değeri olarak yakalanırlar. Küresel fonksiyonlar normalde bir tablo araması kullanılarak işlevin ortamından alınır.

Bilgilerin dosyalar arasında gerçekten paylaşılması gerektiğinde tek bir küresel eklenti tablosunu kullanın.

```lua
someCounter = 0 -- Küresel: mevcut küresel ortamda depolanır.
local someCounter = 0 -- Lokal: sadece bu kapsamda görünür.
-- Dosyaların veri paylaşması gerektiğinde, birçok küresel yerine bir eklenti tablosunu açığa çıkarın.
MyAddon = MyAddon or {}
MyAddon.RoundState = 0
-- Dosya iç uygulama ayrıntılarını yerel tutun.
local internalCounter = 0
```

### Tekrarlanan İş ve Görevlerden Kaçının

Bir değer değişmezse, bir kez hesaplayın veya oluşturun ve tekrar kullanın.

Genellikle kaçırılan önbellek tablosu

- [Renk](https://gmod.tr/wiki/Color)(lar)
- [Vektör](https://gmod.tr/wiki/Vector)(lar)
- [Açı](https://gmod.tr/wiki/Angle)(lar)
- [Malzeme](https://gmod.tr/wiki/IMaterial)(lar)
- [Varlık](https://gmod.tr/wiki/Entity)(-ler)
- [Oyuncu](https://gmod.tr/wiki/Player)(lar)
- [Silah.](https://gmod.tr/wiki/Weapon)(lar)
- Pahalı aramaların sonuçları
- Sabit bir tanımlayıcı ile indekslenmiş veriler

Geçici tablolar oluşturmak gibi, [Renk](https://gmod.tr/wiki/Color)s, [Vektör](https://gmod.tr/wiki/Vector)s veya [Açı](https://gmod.tr/wiki/Angle)Sıkça uygulanan kodlarda, tahsis ve çöp toplama çalışmalarını artırır. [Renk](https://gmod.tr/wiki/Color) ve [Malzeme](https://gmod.tr/wiki/Material)s görüntüleme kancalarının dışında önbelleğe alınmalıdır.

Sonuçları manuel olarak önbelleğe almayın. [player. GetAll](https://gmod.tr/wiki/player.GetAll) Garry'nin Modü sadece oyuncular üzerinde tekrarlamak için sağlar. [player. Iterator](https://gmod.tr/wiki/player.Iterator), iç Lua tarafı önbelleği kullanır ve yeni bir döndürülen tablo oluşturmaktan kaçınır.

```lua
-- Yanlış: nesneleri yaratır veya her kareye pahalı bir arama yapar.
hook.Add( "HUDPaint", "OptimizationExample.BadHUD", function()
	surface.SetMaterial( Material( "icon16/heart.png" ) )
	draw.SimpleText(
		"Healthy",
		"DermaDefault",
		32,
		32,
		Color( 100, 255, 100 ),
		TEXT_ALIGN_LEFT,
		TEXT_ALIGN_TOP
	)
end )

-- Daha iyi: istikrarlı nesneleri bir kez oluşturun ve tekrar kullanın.
local heartMaterial = Material( "icon16/heart.png" )
local healthyColor = Color( 100, 255, 100 )

hook.Add( "HUDPaint", "OptimizationExample.GoodHUD", function()
	surface.SetMaterial( heartMaterial )
	draw.SimpleText(
		"Healthy",
		"DermaDefault",
		32,
		32,
		healthyColor,
		TEXT_ALIGN_LEFT,
		TEXT_ALIGN_TOP
	)
end )
```

```lua
-- Sık sık uygulanan bir kancada olumsuz:
-- player. GetAll tekrarlamak için bir tablo gönderir.
hook.Add( "Tick", "OptimizationExample.BadPlayerIteration", function()
	local alivePlayers = 0
for _, ply in ipairs( player.GetAll() ) do
if ply:Alive() then
			alivePlayers = alivePlayers + 1
end
end
DoSomethingWithCount( alivePlayers )
end )

- Daha iyi:
-- player. Iterator Garry'nin Mod'un içsel olarak korunan oyuncu önbelleğini kullanıyor.
hook.Add( "Tick", "OptimizationExample.GoodPlayerIteration", function()
	local alivePlayers = 0
for _, ply in player.Iterator() do
if ply:Alive() then
			alivePlayers = alivePlayers + 1
end
end
DoSomethingWithCount( alivePlayers )
end )
```

```lua
-- Bu anonim çağrı iyi. hook. Add çalıştırıldığında bir kez oluşturulur.
hook.Add( "Think", "OptimizationExample.NormalClosure", function()
	UpdateGameState()
end )

-- Olumsuz: her tikte bir masa ve birden fazla kapanış yaratır.
hook.Add( "Tick", "OptimizationExample.BadTemporaryClosures", function()
	local actions = {}
for _, ply in player.Iterator() do
		actions[#actions + 1] = function()
			UpdatePlayer( ply )
		end
end
for i = 1, #actions do
		actions[i]()
	end
end )

-- Daha iyi: gecikmiş geri çağrılar gereksiz olduğunda işi doğrudan gerçekleştirin.
hook.Add( "Tick", "OptimizationExample.GoodDirectWork", function()
	for _, ply in player.Iterator() do
UpdatePlayer( ply )
	end
end )
```

### Değişken Nesneleri Tekrar Kullanın

Vektör aritmetiği operatörü genelde yeni bir vektör gönderir. [Vector:Add](https://gmod.tr/wiki/Vector:Add), [Vector:Mul](https://gmod.tr/wiki/Vector:Mul), ve [Vector:Set](https://gmod.tr/wiki/Vector:Set) Ek geçici nesnelerden kaçınabilirsiniz.

```lua
local basePosition = Vector( 100, 200, 300 )
local labelOffset = Vector( 0, 0, 64 )

-- Bir kopyasını ve sonra ekleme sonucu için başka bir vektör oluşturur.
local positionWithExtraAllocation = Vector( basePosition ) + labelOffset

-- Bir kopyasını oluşturur, sonra başka bir toplama sonucu olmadan bu kopya değiştirir.
local positionWithFewerAllocations = Vector( basePosition )
positionWithFewerAllocations:Add( labelOffset )

-- Eğer kalıcı olarak değişmek niyetinde değilseniz bunu yapmayın.
-- basePosition:Add( etiketOffset)
```

### Arama yerine arama tablolarını kullanın

Daha derinlemesine inceleniyor: [Liste Biçimi Tabloları](https://gmod.tr/wiki/List-Styled_Tables).

Bir değerin bilinen bir anahtarı olduğunda, bu anahtarın altında saklayın.

Bir tablonun arama süresi ortalama olarak yaklaşık sabit bir zamandır. Aray aramak, eşleşme bulunana kadar girişleri kontrol etmeyi gerektirir ve bu nedenle girdiler sayısıyla doğrusal büyür.

```lua
local actionList = {
{ Name = "heal", Handler = HealPlayer },
	{ Name = "armor", Handler = GiveArmor },
	{ Name = "respawn", Handler = RespawnPlayer }
}
-- Olumsuz: Aray'ı istenen eylemi bulana kadar tarar.
local function RunActionBySearching( actionName, ply )
	for i = 1, #actionList do
local action = actionList[i]
if action.Name == actionName then
action.Handler( ply )
			return true
end
end
return false
end
-- Daha iyi: onları bulmak için kullanılan değere göre indeks işleyicileri.
local actionHandlers = {
	heal = HealPlayer,
	armor = GiveArmor,
	respawn = RespawnPlayer
}
local function RunActionByLookup( actionName, ply )
	local handler = actionHandlers[actionName]
if not handler then
return false
end
handler( ply )
	return true
end
```

### Sık Kullanılan İşlevleri Yerelleştirin

Tekrarlanan tablo ve küresel aramalar, sıkça function in olarak adlandırılan bir (a) kaydedilerek kaldırılabilir.

Bu, aynı sabit function is sıcak bir yolun içinde birçok kez çağrıldığında en yararlıdır. Bununla birlikte bir denge vardır; her function makes kodunun okunması zorlaşır ve anlamlı bir iyileştirme sağlamayabilir.

```lua
local setDrawColor = surface.SetDrawColor
local drawRect = surface.DrawRect

hook.Add( "HUDPaint", "OptimizationExample.LocalizedFunctions", function()
	for i = 1, 100 do
setDrawColor( 20, 20, 20, 200 )
		drawRect( i * 4, 20, 3, 20 )
	end
end )

-- Yardımcı olan her function without kanıtı yerleştirmekten kaçının.
-- Doğrudan aramalar daha net ve normalde iyi:
hook.Add( "HUDPaint", "OptimizationExample.DirectFunctions", function()
	surface.SetDrawColor( 20, 20, 20, 200 )
	surface.DrawRect( 20, 50, 200, 20 )
end )
```

### Kısıtlı Döngüleri Azaltın

Döngüler programlama için gereklidir.

Bununla birlikte, n büyüklüğündeki bir koleksiyon üzerindeki iki döngü yaklaşık olarak 2 işlem gerçekleştirir.

Örneğin:

- 3 oyuncunun her oyuncuya karşılaştırılması: 9 kıyaslama
- 20 oyuncunun her oyuncuya karşılaştırılması: 400 kıyaslama
- Her oyuncu ile karşılaştırıldığında 100 oyuncu: 10.000 kıyaslama

Köşeli döngüler her zaman yanlış değildir. Çiftli karşılaştırmalar bazı sistemlerde onları gerektirir. Birini kullanmadan önce, aynı işin şu yollarla yapılıp yapılmadığını kontrol edin:

- Bir arama tablosu
- Tek bir geçiş.
- Önce verileri filtrele.
- Uzaysal bölünme
- Sadece değiştirilmiş nesneleri işleme alıyor.

Örnek:

```lua
-- Olumsuz:
-- P oyuncular ve E varlıkları için, bu yaklaşık olarak P * E tekrarlarını gerçekleştirir.
local function UpdateOwnedEntitiesNested()
	for _, ply in player.Iterator() do
for _, ent in ents.Iterator() do
if ent:GetOwner() == ply then
UpdateOwnedEntity( ply, ent )
			end
end
end
end
- Daha iyi:
- Her varlığı bir kez ziyaret edin ve doğrudan sahibini alın.
local function UpdateOwnedEntitiesSinglePass()
	for _, ent in ents.Iterator() do
local owner = ent:GetOwner()

		if IsValid( owner ) and owner:IsPlayer() then
UpdateOwnedEntity( owner, ent )
		end
end
end
```

### Ağ Kullanımı Azaltın

Sadece müşterilerin ihtiyaç duyduğu bilgileri ağlayın ve sadece gerektiğinde gönderin.

Tercihim:

- Değişiklikler her tik yerine meydana geldiğinde gönderilir
- Yayınlama yerine ilgili alıcılara gönderme
- Tüm yapılar yerine kompakt tanımlayıcılar göndermek
- Tam fonksiyonları kullanmak gibi net. WriteBool, net. WriteUInt, ya da net. WriteEntity
- Müşterilerin hesaplamak için yeterli bilgiye sahip oldukları değerleri elde etmelerine izin vermek

[net. WriteTable](https://gmod.tr/wiki/net.WriteTable) Bilinen alanları tam türlerini kullanarak yazmak genellikle daha küçük ve doğrulanması kolaydır. [net. WriteTable](https://gmod.tr/wiki/net.WriteTable) ve [net. WriteUInt](https://gmod.tr/wiki/net.WriteUInt).

Performans tek ağ kaygısı değildir. Sunucu tarafında doğrulanmadan bir istemciden alınan değerlere asla güvenmeyin.

Okumayı düşünün. [Net Kütüphane Kullanımı, Özellikle Geliştirme kısmı](https://gmod.tr/wiki/Net_Library_Usage#improving).

```lua
if SERVER then
util.AddNetworkString( "OptimizationExample.RoundStateChanged" )

	local currentRoundState = 0
local function SetRoundState( newState )
		-- Bu örnekte geçerli değerler 0 ila 7.
		newState = math.Clamp( math.floor( newState ), 0, 7 )

		- Değişiklik yoksa haber göndermeyin.
if newState == currentRoundState then
return
end

		currentRoundState = newState

		net.Start( "OptimizationExample.RoundStateChanged" )
			net.WriteUInt( currentRoundState, 3 )
		net.Broadcast()
	end
-- Sadece bir oyun olayı durumu değiştirdiğinde SetRoundState'i ara.
-- Mevcut değeri yeniden göndermek için Tick'ten çağırmayın.
end
if CLIENT then
net.Receive( "OptimizationExample.RoundStateChanged", function()
		local newRoundState = net.ReadUInt( 3 )
		UpdateRoundInterface( newRoundState )
	end )
end
```

## Mikro Optimizasyonlar

Mikro optimizasyonlar daha büyük sorunların ele alınmasından sonra gelmelidir.

En uygun durumları şunlardır:

- Sistem zaten doğru ve eksiksiz.
- Profilleme, kodu önemli olarak tanımlar.
- Kod çok sık çalıştırılıyor.
- Optimize edilmiş sürüm sürdürülebilir kalır.

#### Sıralı dizilere doğrudan uygulayın

Görevi: `#tbl + 1` Çağırmaktan daha hızlı olabilir. [table.insert](https://gmod.tr/wiki/table.insert) yoğun bir diziye eklenirken.

Bu sadece eklemeye eşittir. Kullanmaya devam edin [table.insert](https://gmod.tr/wiki/table.insert) Belirli bir pozisyonda yerleştirildiğinde veya niyeti daha net olduğunda.

```lua
local values = {}
local value = 7
-- Açık ve okunur:
table.insert( values, value )

-- Sadece ekleme yoğun dizileri için potansiyel olarak daha hızlı:
values[#values + 1] = value

-- Belirli bir konumda yerleştirildiğinde bunlar eşdeğer değildir:
table.insert( values, 1, value )
```

#### Tekrarlanan Matematiği Basitleştirin

Bazı matematiksel eşdeğer ifadeler daha az işlem gerektirir:

- Karşılaştırma ile çarpım bölünmenin yerini alabilir.
- x*x, katlanımı iki ile değiştirebilir.
- Faktörlendirme tekrarlanan çarpımları ortadan kaldırabilir.

```lua
local x = 10
local y = 20
local z = 30
-- Sabitle bölme:
local halfA = x / 2
local halfB = x * 0.5
-- Karesi:
local squaredA = x ^ 2
local squaredB = x * x

-- Faktörleştirme bir çarpımı ortadan kaldırır:
local resultA = x * y + x * z + y * z
local resultB = x * ( y + z ) + y * z

-- Profillemenin
-- alternatif tam olarak bu sıcak yolda anlamlı bir gelişme sağlar.
```

## Önemli İlgili Kaynaklar

- [https://gitspartv.github.io/LuaJIT-Benchmarks/](https://gitspartv.github.io/LuaJIT-Benchmarks/)

  - "Mikro-Pico Optimizasyonlar"a odaklanıyor.
- [https://github.com/FPtje/FProfiler](https://github.com/FPtje/FProfiler)

  - Kodunuzdaki engelleri bulmanıza yardımcı olacak bir profiler

- [GMod Wiki ana sayfası](https://gmod.tr/wiki)

---

[Tüm sunucular](https://gmod.tr/) · [GmodTR Launcher](https://gmod.tr/launcher) · [Rehber](https://gmod.tr/rehber) · [GMod Wiki](https://gmod.tr/wiki) · [GmodTR nedir?](https://gmod.tr/hakkinda) · [Sunucu ekle](https://gmod.tr/sunucu-ekle) · [Discord](https://discord.gg/gmodtr)

Kaynak: https://gmod.tr/wiki/optimizationTips
