C# Basit bir hesap makinesi

Evet son örnek çok büyük bir performans kaybı yaşatmaz fakat her seferinde motora veri tipini belirtmek yerine 1 kere belirtip 1 den fazla ad, değer verilmesi daha performanslı. Bu işlem büyük işlere başlandığında göz arkasına alınacak bir işlem değil.

İki işlemde de 4 tane int tanımlanıyor, hafıza kullanımı aynı, buna ilaveten c#, java gibi dillerin compilerları her ikisini de aynı yorumlayacak diye biliyorum, yani kodunuzu daha . Neye göre daha performanslı diyorsunuz, hangi büyük işte bunu kullanıp da performans sorununa denk geldiniz? Performans konusunu arattım internette bir şey bulamadım, official bir kaynak paylaşırsanız hak vereceğim, yoksa bu bilginiz yanlış.

Benim demek istediğimi anlamadınız if i kullanmamın sebebi fazla kodu önlemek ayrıca eğer işi daha da ilerletmek istiyorsan if'e gerek yok:

Sizin anlatmaya çalıştığınızı elbette anladım ancak örneğiniz sıkıntılı demek istemiştim, şöyle izah edeyim.

if (dogruMu != false || dogruMu == true) // bu kötü, haklısınız

onun yerine

if (dogruMu) // bu iyi

ama if'in içinde yaptığınız işlemi de işin içine katarsak

Kod:
if (dogruMu != false || dogruMu == true) // '||' işareti, matematikteki 'veya' anlamını taşır.
{
   dogruMu = false
}

mantık olarak

Kod:
if (dogruMu)
    dogruMu = false;
if (!yanlisMi) // ünlem 'zıt' anlamı taşır yani burada false
    yanlisMi = true;

buna eşit

o da

Kod:
dogruMu = false;

bu koda eşit. Sıkıntılı dememin sebebi bu idi, yoksa tabi ki
if (dogruMu != false || dogruMu == true)
yerine
if (dogruMu)
yazılmalı, if'in içini daha iyi hale getirmişsiniz. Sadece "dogruMu = false" bölümü dikkatimi çekmişti.
 
İki işlemde de 4 tane int tanımlanıyor, hafıza kullanımı aynı, buna ilaveten c#, java gibi dillerin compilerları her ikisini de aynı yorumlayacak diye biliyorum, yani kodunuzu daha . Neye göre daha performanslı diyorsunuz, hangi büyük işte bunu kullanıp da performans sorununa denk geldiniz? Performans konusunu arattım internette bir şey bulamadım, official bir kaynak paylaşırsanız hak vereceğim, yoksa bu bilginiz yanlış.



Sizin anlatmaya çalıştığınızı elbette anladım ancak örneğiniz sıkıntılı demek istemiştim, şöyle izah edeyim.

if (dogruMu != false || dogruMu == true) // bu kötü, haklısınız

onun yerine

if (dogruMu) // bu iyi

ama if'in içinde yaptığınız işlemi de işin içine katarsak

Kod:
if (dogruMu != false || dogruMu == true) // '||' işareti, matematikteki 'veya' anlamını taşır.
{
   dogruMu = false
}

mantık olarak

Kod:
if (dogruMu)
    dogruMu = false;
if (!yanlisMi) // ünlem 'zıt' anlamı taşır yani burada false
    yanlisMi = true;

buna eşit

o da

Kod:
dogruMu = false;

bu koda eşit. Sıkıntılı dememin sebebi bu idi, yoksa tabi ki
if (dogruMu != false || dogruMu == true)
yerine
if (dogruMu)
yazılmalı, if'in içini daha iyi hale getirmişsiniz. Sadece "dogruMu = false" bölümü dikkatimi çekmişti.
dogruMu = false; kısmı örnek. Yani evet true olup olmamasına bakmamıza gerek yok. Ancak örnek verdim yani ordaki amaç sadece "== true" yazısını kaldırmasını istediğim ayrıca ilk dediğinize gelecek olursak:
Bunu anlatmada biraz güçlük çekeceğim senin için,
Motorlar yukarıdan aşağıya soldan sağa kodları okur.
Sen motora int a, b, c; dersen başta Integer bir değişken olduğunu bildiği için diğerlerini "?" olarak algılamaz. Yani her seferinde sen string misin? int misin? double mısın? float mısın? sorusunu engelliyorsun + Kod kalabalığını önlüyorsun. 'Boşluklar hariç' kullandığın her harf ve rakamlar 'Motorun' okuma hızını yavaşlatıyorsun. Tabii ki şaunki işlemciler eskilere göre çok çok daha güçlü olduğundan bu farkı farketmek pek mümkün değil. Ancak eğer bu dediklerim Yüzlerce hatta binlerce kez yazılırsa hissedilebilir bir fark olur.
 
dogruMu = false; kısmı örnek. Yani evet true olup olmamasına bakmamıza gerek yok. Ancak örnek verdim yani ordaki amaç sadece "== true" yazısını kaldırmasını istediğim ayrıca ilk dediğinize gelecek olursak:
Bunu anlatmada biraz güçlük çekeceğim senin için,
Motorlar yukarıdan aşağıya soldan sağa kodları okur.
Sen motora int a, b, c; dersen başta Integer bir değişken olduğunu bildiği için diğerlerini "?" olarak algılamaz. Yani her seferinde sen string misin? int misin? double mısın? float mısın? sorusunu engelliyorsun + Kod kalabalığını önlüyorsun. 'Boşluklar hariç' kullandığın her harf ve rakamlar 'Motorun' okuma hızını yavaşlatıyorsun. Tabii ki şaunki işlemciler eskilere göre çok çok daha güçlü olduğundan bu farkı farketmek pek mümkün değil. Ancak eğer bu dediklerim Yüzlerce hatta binlerce kez yazılırsa hissedilebilir bir fark olur.
Ben size çok basitçe anlatmaya çalışayım, yazdığınız c# kodunda aynı satırda ya da alt alta 4 satırda int tanımladığınızda
-derleme yaptığınızda compiler (motor?) hmm, kodu yazan kişi 4 tane int kullanacakmış, o zaman ben bir tabloda a, b, c ve d isimlerinde 4 tane değişken yaratayım, bellekte de bunlar için 4er byte'lık yer ayırayım der.
-çalışma esnasında da compiler bunların adreslerini bildiği için erişmenizi sağlar, yani a=10 derseniz de a=b derseniz de ya a'ya 10 sayısını ya da b sayısı bellekte o sırada hangi sayıyı tutuyorsa onu a'ya atar.

Buna ilaveten, insanların yazdığı kodlar compiler tarafından da optimize edilir. Yani sizin vermiş olduğunuz örnek vardı ya;

if (dogruMu != false || dogruMu == true)

Günümüz compilerları zaten bu kodu

if(dogruMu)

şeklinde optimize ediyor, yani kötü yazılmış kodu böyle düzeltebiliyor diyeyim, böylece çalışırken gereksiz kontrollerden kendisi kurtulacak kadar zeki. Ya da sabit bir sayı olsun

int a = 5*5*5 - 25;

compiler bytecode üretirken

int a = 100; diye sabit olarak ayarlıyor.

Bunu şuna bağlayacağım, sizin dediğiniz şekilde a,b,c diye tek satırda declare edildi o zaman iyi çalışır, farklı satırlarda yapınca sen string misin, sen float mısın vs. tarzı bir sorun yaşanmıyor, compiler zaten siz aynı satırda da yazsanız, 4 satırda da yazsanız; compile zamanında 4 tane int mi lazım, tamam, yarattım bitti gitti diyecek kadar zeki, öyle okuma hızı falan da yavaşlamıyor, sizin dediğiniz işlemci gücünün artması ile artık fark edilmeyecek performans sorunlarına dahil bir şey değil bu.

Bu sebeple siz c# dokümantasyonu vb. bir kaynaktan; bu durumda compilera yük biner, değişkenleri ? olarak algılar, senin tipin nedir diye şaşırır kalır diye bir kural, best practice örneği vs. gösterirseniz yanlış biliyormuşum, siz haklıymışsınız diyeceğim.
 
Ben size çok basitçe anlatmaya çalışayım, yazdığınız c# kodunda aynı satırda ya da alt alta 4 satırda int tanımladığınızda
-derleme yaptığınızda compiler (motor?) hmm, kodu yazan kişi 4 tane int kullanacakmış, o zaman ben bir tabloda a, b, c ve d isimlerinde 4 tane değişken yaratayım, bellekte de bunlar için 4er byte'lık yer ayırayım der.
-çalışma esnasında da compiler bunların adreslerini bildiği için erişmenizi sağlar, yani a=10 derseniz de a=b derseniz de ya a'ya 10 sayısını ya da b sayısı bellekte o sırada hangi sayıyı tutuyorsa onu a'ya atar.

Buna ilaveten, insanların yazdığı kodlar compiler tarafından da optimize edilir. Yani sizin vermiş olduğunuz örnek vardı ya;

if (dogruMu != false || dogruMu == true)

Günümüz compilerları zaten bu kodu

if(dogruMu)

şeklinde optimize ediyor, yani kötü yazılmış kodu böyle düzeltebiliyor diyeyim, böylece çalışırken gereksiz kontrollerden kendisi kurtulacak kadar zeki. Ya da sabit bir sayı olsun

int a = 5*5*5 - 25;

compiler bytecode üretirken

int a = 100; diye sabit olarak ayarlıyor.

Bunu şuna bağlayacağım, sizin dediğiniz şekilde a,b,c diye tek satırda declare edildi o zaman iyi çalışır, farklı satırlarda yapınca sen string misin, sen float mısın vs. tarzı bir sorun yaşanmıyor, compiler zaten siz aynı satırda da yazsanız, 4 satırda da yazsanız; compile zamanında 4 tane int mi lazım, tamam, yarattım bitti gitti diyecek kadar zeki, öyle okuma hızı falan da yavaşlamıyor, sizin dediğiniz işlemci gücünün artması ile artık fark edilmeyecek performans sorunlarına dahil bir şey değil bu.

Bu sebeple siz c# dokümantasyonu vb. bir kaynaktan; bu durumda compilera yük biner, değişkenleri ? olarak algılar, senin tipin nedir diye şaşırır kalır diye bir kural, best practice örneği vs. gösterirseniz yanlış biliyormuşum, siz haklıymışsınız diyeceğim.
Yani sonuç olarak yinede fazladan motoru çalıştırmıyor musun? Kendinde diyorsun işte
int a = 5*5*5 - 25;
değerini int = 100 yapmak için de bir işlem yapmıyor mu motor?
Benim kastettiğim şey de tam olarak bu
Motora yaptırmak yerine kendin doğru yaz ki tekrar onu düzeltmekle efor sarfetmesin.
 
Merhaba dosya iOS cihazda açılırmı.
 
Yani sonuç olarak yinede fazladan motoru çalıştırmıyor musun? Kendinde diyorsun işte
int a = 5*5*5 - 25;
değerini int = 100 yapmak için de bir işlem yapmıyor mu motor?
Benim kastettiğim şey de tam olarak bu
Motora yaptırmak yerine kendin doğru yaz ki tekrar onu düzeltmekle efor sarfetmesin.
Compilerın optimizasyon yapacak kadar zeki bir yapı olduğunu size anlatabildiysem, tek satır ya da çok satırda tanımlanan değişkenlere de gülüp geçeceğini anlamışsınızdır diye ümit ediyorum, amacım buydu en azından.

Compiler için; sizin yazdığınız
int a,b,c;
ve
int a;
int b;
int c;

aynı şeylerdir.

Böyle yazılmış bir kod compiler optimizasyonuna bile girmez, çünkü performans etkileyecek bir şey değildir, mesela gereksiz yere kullanılan bir değişken yoktur, compiler her halükarda 4 tane int tanımlar, sizin dediğiniz gibi alt alta yazılmış, o zaman durup dinlene dinlene ram allocate edeyim, yavaş olayım, 4 yerine 8 byte kullanayım vs. demez.



Benim anlattıklarımı anlamadığınızı, pek çok terime de hakim olmadığınızı düşünüyorum (kaç yaşında adamım, compilera motor diyen insana ilk defa denk geldim) Tek satırda değişken tanımlamaya dair kaynak varsa paylaşın biz de öğrenelim demiştim, ya okuduğunuzu anlamıyorsunuz, ya kaynak arıyor bulamıyorsunuz ya da arama yapacak teknik bilgi/ingilizce vb. donanımlara sahip değilsiniz ve yanlış/yarım yamalak bilgi ile (kod okunabilirliğini optimizasyon sanmak gibi yani) ahkam kesmek daha çok keyif veriyor, iletişim kurmamız çok zor, bu sebeple esen kalın.
 
Compilerın optimizasyon yapacak kadar zeki bir yapı olduğunu size anlatabildiysem, tek satır ya da çok satırda tanımlanan değişkenlere de gülüp geçeceğini anlamışsınızdır diye ümit ediyorum, amacım buydu en azından.

Compiler için; sizin yazdığınız
int a,b,c;
ve
int a;
int b;
int c;

aynı şeylerdir.

Böyle yazılmış bir kod compiler optimizasyonuna bile girmez, çünkü performans etkileyecek bir şey değildir, mesela gereksiz yere kullanılan bir değişken yoktur, compiler her halükarda 4 tane int tanımlar, sizin dediğiniz gibi alt alta yazılmış, o zaman durup dinlene dinlene ram allocate edeyim, yavaş olayım, 4 yerine 8 byte kullanayım vs. demez.



Benim anlattıklarımı anlamadığınızı, pek çok terime de hakim olmadığınızı düşünüyorum (kaç yaşında adamım, compilera motor diyen insana ilk defa denk geldim) Tek satırda değişken tanımlamaya dair kaynak varsa paylaşın biz de öğrenelim demiştim, ya okuduğunuzu anlamıyorsunuz, ya kaynak arıyor bulamıyorsunuz ya da arama yapacak teknik bilgi/ingilizce vb. donanımlara sahip değilsiniz ve yanlış/yarım yamalak bilgi ile (kod okunabilirliğini optimizasyon sanmak gibi yani) ahkam kesmek daha çok keyif veriyor, iletişim kurmamız çok zor, bu sebeple esen kalın.
Kendim şuan profesyonel yazılım geliştiriciyim. Motor ile compilera takılmanız çok saçma olmuş. Geliştirdiğim uygulamalardan biri bilgisayarın sağlığını/performansını vb. şeyleri kontrol ettiği için zamanında hem o konulara hemde kod optimizasyonu konusunu çok araştırmıştım türk ve yabancı kaynaklardan.
 
Motorlar yukarıdan aşağıya soldan sağa kodları okur.
Motor diye bir şey yok. Interpreter o. Yorumlayıcı eğer illa Türkçe konuşacaksan. C#'da interpreted değil. JIT compiled. JIT Compiled dillerde ve ahead of time compiled dillerde declaration'ı ister one liner yap, istersen 50 satırda yap. Fark etmeyecek performans açısından.
Sen motora int a, b, c; dersen başta Integer bir değişken olduğunu bildiği için diğerlerini "?" olarak algılamaz. Yani her seferinde sen string misin? int misin? double mısın? float mısın? sorusunu engelliyorsun + Kod kalabalığını önlüyorsun
Compiler'ın görevini bilmediğinden bu yorumu yaptığını varsayıyorum. Yoksa bu kadar anlamsız başka bir yorum yok. Compile süresini etkilerse (ki o da meçhul) bir onu etkiler.
Bunu anlatmada biraz güçlük çekeceğim senin için,
Yukarıdan bakman cabası. Azıcık mesajlarını okusan karşındakinin, senden aşağı kalır bilgisi olmadığını fark edersin.
'Boşluklar hariç' kullandığın her harf ve rakamlar 'Motorun' okuma hızını yavaşlatıyorsun. Tabii ki şaunki işlemciler eskilere göre çok çok daha güçlü olduğundan bu farkı farketmek pek mümkün değil. Ancak eğer bu dediklerim Yüzlerce hatta binlerce kez yazılırsa hissedilebilir bir fark olur.
Compile'a etkisi, evet var. Runtime'a etkisi, hayır yok. Binlerce değil milyonlarca satır kod bloğuna sahip sistemler var cayır cayır çalışıyorlar. Interpreted dil kullanmıyoruz. Python değil bu. Python'da bile evaluation'ı etkilemek sandığın kadar kolay değil de, varsayalım o kadar kolay olsun.
Yani sonuç olarak yinede fazladan motoru çalıştırmıyor musun? Kendinde diyorsun işte
int a = 5*5*5 - 25;
değerini int = 100 yapmak için de bir işlem yapmıyor mu motor?
Benim kastettiğim şey de tam olarak bu
Motora yaptırmak yerine kendin doğru yaz ki tekrar onu düzeltmekle efor sarfetmesin.
Israrla motor motor... Ne bu engine? Neyin engine'i? Sen C# ile kod yazdığında, yazdığın kod önce MSIL'e dönüşür. (Microsoft Intermediate Language), bu .NET çatısı altında yer alan dillerin her biri için ayrı ayrı RT vm yada JIT compiler yazılması gerekliliğini önlüyor. C#, F#, VB.NET gibi dilleri compile ettiğinde ürettiği MSIL daha sonrasında JIT compiler'a çalıştırılmak için veriliyor. (.NET Core, .NET Framework vs.) Bu JIT compilerlar ise MSIL kodu byte code'a çevirip execute ediyor. Line by line execution bu noktada gerçekleşiyor. Fakat senin başta verdiğin
int a;
int b;
int c;

çoktan başka bir şeye dönüştü bile. Hatta şöyle anlatsam senin adına daha anlaşılır olacak muhtemelen.
1717546323715.png


Bak şimdi, C# compiler'a bu kodu vereceğim. Gördüğün üzere a, b ve c tek line, d, e ve f ayrı ayrı linelar. Bakalım compiler generated IL kodu neymiş?
1717546520627.png

1717547189767.png

Aa? O da ne? Hiç biri tek lineda değil. Eyvah! "Motor" aşırı yoruluyor! Şimdi attığım ekran görüntülerine inanmazsın falan. Gidip SharpLab üzerinden yada Resharper Tools ile kendin de test edebilirsin.
Benim anlattıklarımı anlamadığınızı, pek çok terime de hakim olmadığınızı düşünüyorum (kaç yaşında adamım, compilera motor diyen insana ilk defa denk geldim)
JIT Compiler'a execute ediyor diye engine diyor sanırım. Interpreted dillerle karıştırdı galiba. Compiler ne deseniz Google'a bakmadan cevap veremeyecek adam vaktiyle bir yerden duymuş engine diye bir şey. Ahkam kesiyor. Hayır forumda onca adam varken size "Sana anlatmada zorluk çekeceğim" gibi bir cümle kurması daha da absürt.
 
Motor diye bir şey yok. Interpreter o. Yorumlayıcı eğer illa Türkçe konuşacaksan. C#'da interpreted değil. JIT compiled. JIT Compiled dillerde ve ahead of time compiled dillerde declaration'ı ister one liner yap, istersen 50 satırda yap. Fark etmeyecek performans açısından.

Compiler'ın görevini bilmediğinden bu yorumu yaptığını varsayıyorum. Yoksa bu kadar anlamsız başka bir yorum yok. Compile süresini etkilerse (ki o da meçhul) bir onu etkiler.

Yukarıdan bakman cabası. Azıcık mesajlarını okusan karşındakinin, senden aşağı kalır bilgisi olmadığını fark edersin.

Compile'a etkisi, evet var. Runtime'a etkisi, hayır yok. Binlerce değil milyonlarca satır kod bloğuna sahip sistemler var cayır cayır çalışıyorlar. Interpreted dil kullanmıyoruz. Python değil bu. Python'da bile evaluation'ı etkilemek sandığın kadar kolay değil de, varsayalım o kadar kolay olsun.

Israrla motor motor... Ne bu engine? Neyin engine'i? Sen C# ile kod yazdığında, yazdığın kod önce MSIL'e dönüşür. (Microsoft Intermediate Language), bu .NET çatısı altında yer alan dillerin her biri için ayrı ayrı RT vm yada JIT compiler yazılması gerekliliğini önlüyor. C#, F#, VB.NET gibi dilleri compile ettiğinde ürettiği MSIL daha sonrasında JIT compiler'a çalıştırılmak için veriliyor. (.NET Core, .NET Framework vs.) Bu JIT compilerlar ise MSIL kodu byte code'a çevirip execute ediyor. Line by line execution bu noktada gerçekleşiyor. Fakat senin başta verdiğin
int a;
int b;
int c;

çoktan başka bir şeye dönüştü bile. Hatta şöyle anlatsam senin adına daha anlaşılır olacak muhtemelen.
Eki Görüntüle 2213420

Bak şimdi, C# compiler'a bu kodu vereceğim. Gördüğün üzere a, b ve c tek line, d, e ve f ayrı ayrı linelar. Bakalım compiler generated IL kodu neymiş?
Eki Görüntüle 2213422
Eki Görüntüle 2213426
Aa? O da ne? Hiç biri tek lineda değil. Eyvah! "Motor" aşırı yoruluyor! Şimdi attığım ekran görüntülerine inanmazsın falan. Gidip SharpLab üzerinden yada Resharper Tools ile kendin de test edebilirsin.

JIT Compiler'a execute ediyor diye engine diyor sanırım. Interpreted dillerle karıştırdı galiba. Compiler ne deseniz Google'a bakmadan cevap veremeyecek adam vaktiyle bir yerden duymuş engine diye bir şey. Ahkam kesiyor. Hayır forumda onca adam varken size "Sana anlatmada zorluk çekeceğim" gibi bir cümle kurması daha da absürt.
Görselle anlatmak iyi fikirmiş😀

Java (jit kullanan diğer bir dil) için de intellij üzerinden şöyle incelenebilir diye ek bilgi vereyim forum kullanıcılarına;

Kod:
public void test()
{
int a,b,c;
int d;
int e;
int f;

a =5;
b =5;
c =5;
d =5;
e =5;
f =5;

int z=a+b+c+d+e+f;

if(z>5)
   {
System.out.println("asd");
   }
}

Bu derlenip .class uzantılı dosya oluşturulduğunda

Kod:
public void test() {
int a = 5;
int b = 5;
int c = 5;
int d = 5;
int e = 5;
int f = 5;
int z = a + b + c + d + e + f;
if (z > 5) {
System.out.println("asd");
    }

}

Halini alır, yukarda aynı satırda int demişsin, alt alta satırlarda int demişsin takmıyor yani. Programcının kendi zevkine ya da şirketinizin code format prensipleri varsa ona göre yapılacak bir tanımlama. Intellij->View->Show Byte Code denirse oluşan bytecode da şöyle incelenebilir;

Kod:
public test()V
   L0
    LINENUMBER 37 L0
    ICONST_5
    ISTORE 1
   L1
    LINENUMBER 38 L1
    ICONST_5
    ISTORE 2
   L2
    LINENUMBER 39 L2
    ICONST_5
    ISTORE 3
   L3
    LINENUMBER 40 L3
    ICONST_5
    ISTORE 4
   L4
    LINENUMBER 41 L4
    ICONST_5
    ISTORE 5
   L5
    LINENUMBER 42 L5
    ICONST_5
    ISTORE 6
   L6
    LINENUMBER 44 L6
    ILOAD 1
    ILOAD 2
    IADD
    ILOAD 3
    IADD
    ILOAD 4
    IADD
    ILOAD 5
    IADD
    ILOAD 6
    IADD
    ISTORE 7
   //... L6ya kadar tanımlamalar, burada toplama işlemini falan yapıyor, bundan sonra böyle devam ediyor

Yani tek satır combined ve alt alta satırlardaki tanımlamaların neticesinin runtimeda farklı olmadığı görülebiliyor.

Alt alta yazılmış ya da tek satırda yazılmış intleri compiler nasıl parse ediyor işlemi de şöyle bir şey

1717596779533.png

-> Abstract syntax tree - Wikipedia biraz okunursa compiler için çocuk oyuncağı bir şey olduğu anlaşılır, bu sebeple oradaki alt alta yazılmış değişkenler performans sorunu yaratır demek saçma. Bunun code optimisation ile alakasını kurmaya çalışmak da saçma, değişken sayısı abartı derecede arttığı durumlarda (bu da code smell aslında) ne kadar berbat bir görüntü oluşturacağı tahmin edilebilir.

Alakalı java code convention ile ilgili şöyle bir şey de iliştiriyorum, tek satırı tercih etmeyin diyor.


Merak eden, sorgulayan, öğrenmek isteyen incelesin madem, farklı bilgi/kaynaklar bulan tartışılacak seviyedeki arkadaşlarla da fikir alışverişi yapabiliriz, neticede biz de okulda her şeyi öğrenmedik ama doğru mu, yanlış mı, bilgim eksik mi, outdated mı, daha iyisi var mı vb. konularda sabit fikirli olmamayı öğrettiler, ben böyle biliyorum o zaman doğrusu budur dememek lazım, iyi forumlar herkese.
 
Son düzenleme:

Technopat Haberler

Yeni konular

Geri
Yukarı