Forum: Ders Arası RSS
Array içerisinde array kullanımı
Sayfa:  önceki  1  2  3  sonraki 
acehreli (Moderatör) #16
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 8170
Çok yararlı olduğu konusunda haklısın. Ancak, bütün bu türler senin örneğinde toString() ile birleşmiş durumdalar.

Bir Köprü[] dizisini işlemek için bir işlev yazdığın zaman çektiğin elemanların asıl türlerinin ne oldukları açık olmayabilir:
void foo(Köprü[] veri)
{
    // Elemanların türleri ne?
}
Aşılmaz bir sorun diye söylemiyorum ama eğer Köprü arayüzünde toString()'den başka işlevler olamıyorsa kullanışlılık düşmüş oluyor.

Ali
Avatar
zekeriyadurmus #17
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Variant işimi gördü ama

import std.stdio;
import std.variant;
import std.datetime;
 
void on()
{
    auto var = Variant(5);
    int i = var.get!int;
}
 
void off()
{
    auto var = 5;
    int i = var;
}
 
void main()
{
    writeln(benchmark!(on, off)(100000));
    while (1){}
}

teste tabi tuttuğumda oldukça yavaş çıktı bir iki işlem yaptıkça da bu süre giderek uzuyor. Variant gibi başka bir kullanım ne önerirsiniz?
Bilgi meraktan gelir...
acehreli (Moderatör) #18
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yavaş derken neyle karşılaştırıyorsun? Tabii ki herşeyin bir bedeli var. dmd'nin şu seçenekleri işe yarayabilir:

dmd ... -O -release -inline

Belki Variant'ın gerçekleştirmesi yavaştır; ileride hızlanması beklenebilir. gdc veya başka bir derleyici düşünebilir.

Ali
Avatar
zekeriyadurmus #19
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
String ile veya herhangi bir veri türü ile karşılaştırıyorum


tip olarak string olarak belirtip benchmark testine tabi tuttuğumda 100 ms Variant olarak belirttiğimde ise 1200ms sürüyor. Bu yavaşlıktan bahsediyorum aslında.
 
struct Foo
{
 
    int opApply(int delegate(string) dg){
        int result;
        int i;
        while(i<10000)
        {
            i++;
            result = dg("asdqewqeqwe");
            if(result)
                break;
        }
        return result;
    }
}
Foo foo;
 
void x(){
    foreach(item; foo){
    }
}
 
void main()
{
    writeln(benchmark!(x)(1));
    while (1){
    }
}
Bilgi meraktan gelir...
Avatar
zekeriyadurmus #20
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ve ayrıca çok şaşırtıcı ama dizi toplama işlemleri oldukça uzun sürüyor

x ~= item;

dediğimde süre 2500 çıkarken     x ~= item; satırını silersem süre 200 çıkıyor.

Bu işlemi daha hızlı yapmanın bir yolu var mı?

Kusura bakmayın bu arada yapacağımız dilin gerçekten performanslı birşey olmasını istiyoruz. Bu yüzden bu kadar inceliyorum. her satırında <!print("asdqwewq")!> yazan 2600 satır, 60kb lık bir dosyayı parse etmeyi başlattığımda diziye sürekli değer attığım için oldukça uzun sürüyor.

Bu süre kısa olması lazım bunun için uğraşıyorum :/
Bilgi meraktan gelir...
Bu mesaj zekeriyadurmus tarafından değiştirildi; zaman: 2012-10-31, 12:34.
Avatar
zekeriyadurmus #21
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ve ayrıca

import std.datetime, std.stdio, std.variant;
 
auto fib(Int)()
{
    Int a = 1, b = 1;
    for(size_t i=0; i<100; i++){
        Int c = a + b;
        a = b;
        b = c;
    }
    return a;    
}
 
void main()
{
    writeln(benchmark!(fib!int, fib!long, fib!Variant)(10_000));
}

kodunu denediğimiz de ise sonuç gerçekten içler acısı

[TickDuration(197), TickDuration(276), TickDuration(93370107)]

Acaba veri depolamak için daha iyi bir yol var mı?
Bilgi meraktan gelir...
acehreli (Moderatör) #22
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #19
zekeriyadurmus:
String ile veya herhangi bir veri türü ile karşılaştırıyorum

Ama onlar burada istenenleri karşılayamıyorlar değil mi? Yalnızca tamsayı veya yalnızca dizgi tutabilen bir tür ile her türü tutabilen Variant'ı karşılaştıramayız herhalde.

Doğrusu ben Variant'ın da doğru çözüm olduğundan emin değilim. Salih'e sorduğum soru hâlâ geçerli: Dosyadan taradık ve bir dizi Variant edindik diyelim. Daha sonra bunlarle ne yapabiliriz? Nereden bilebiliriz her Variant'ın içinde hangi asıl tür var?

Ali
acehreli (Moderatör) #23
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #21
zekeriyadurmus:
kodunu denediğimiz de ise sonuç gerçekten içler acısı

Doğru. Variant temel türlerin yanına yaklaşamaz.

Ali
acehreli (Moderatör) #24
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #20
zekeriyadurmus:
dizi toplama işlemleri oldukça uzun sürüyor

Evet, D'nin dizileri ve dilimleri çok akıllıca tasarlanmış olan çok hızlı olanaklardır. Örneğin C'nin dizileri D dizilerinin yanına bile yaklaşamaz. C++'ın vector'ü de çöp toplayıcı bulunmadığı için ekleme işlemlerinde D'den daha yavaş kalmak zorundadır.

Buna rağmen, std.array.Appender'ın daha hızlı olduğu söyleniyor. Ona bakabilirsin.

Dizilerle ilgili olarak şu makaleyi (ve orada bağlantısı bulunan İngilizcesini) öneririm:

  http://ddili.org/makale/d_dilimleri.html

Kusura bakmayın bu arada yapacağımız dilin gerçekten performanslı birşey olmasını istiyoruz. Bu yüzden bu kadar inceliyorum.

Tabii ki incelemelisiniz. :) D ile yazılmış bir D derleyicisi var. Belki onların nasıl yaptıklarına da bakılabilir:

  https://github.com/azizk/dil

her satırında <!print("asdqwewq")!> yazan 2600 satır, 60kb lık bir dosyayı parse etmeyi başlattığımda diziye sürekli değer attığım için oldukça uzun sürüyor.

Acaba beklentilerimiz mi farklı? Şöyle bir program dosyaya yazma işi de dahil olmak üzere 0.015 saniye kadar sürüyor. Yavaş mı? Herhalde başka derleyicilerle daha hızlı olabilir. (?)

import std.stdio;
import std.array;
 
class Komut
{
    abstract void işlet();
}
 
class Print : Komut
{
    string mesaj;
 
    this(string mesaj)
    {
        this.mesaj = mesaj;
    }
 
    override void işlet()
    {
        writefln("%s mesajını yazdırıyorum", mesaj);
    }
}
 
Komut tara(string satır)
{
    // Artık tarama nasıl oluyorsa. Ben tembellik yapacağım ve komutun 'print'
    // olduğunu varsayacağım ve yalnızca çift tırnaklar arasını alacağım.
 
    // Baştan kırp
    while (!satır.empty && (satır.front != '"')) {
        satır.popFront();
    }
 
    while (!satır.empty && (satır.back != '"')) {
        satır.popBack();
    }
 
    return new Print(satır);
}
 
void yaz(string dosyaİsmi)
{
    auto dosya = File(dosyaİsmi, "w");
 
    foreach (i; 0 .. 2600) {
        dosya.writeln(`<!print("asdqwewq")!>`);
    }
}
 
Komut[] oku(string dosyaİsmi)
{
    Komut[] komutlar;
    auto dosya = File(dosyaİsmi, "r");
 
    foreach (satır; dosya.byLine) {
        komutlar ~= tara(satır.idup)// Buradaki .idup çok önemli çünkü
                                       // byLines hep kendi içindeki bir
                                       // satırı kullanır.
    }
 
    return komutlar;
}
 
void main()
{
    auto dosyaİsmi = "print_komutu_deneme_dosyasi";
    yaz(dosyaİsmi);
    Komut[] komutlar = oku(dosyaİsmi);
    foreach (komut; komutlar) {
        komut.işlet();
    }
}

$ time ./deneme > /dev/null

real    0m0.015s
user    0m0.004s
sys    0m0.010s


Ali
Avatar
Salih Dinçer #25
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #22
acehreli:
Doğrusu ben Variant'ın da doğru çözüm olduğundan emin değilim. Salih'e sorduğum soru hâlâ geçerli: Dosyadan taradık ve bir dizi Variant edindik diyelim. Daha sonra bunlarle ne yapabiliriz? Nereden bilebiliriz her Variant'ın içinde hangi asıl tür var?
Ben de bu yüzden Variant sınıfını kullanmadan klasik bir şekilde Interface (aslında abstract class öyle değil mi hocam?) kullanarak çözmeye çalıştım. Bunu yaklaşık 24 saattir yapıyorum...:)

Düşünün, dünden beri dışarıda, yemek yerken, yürürken ve hatta uykumda çözmeye çalışıyorum. Adeta kaput oldum çünkü türü arayüze versen bir türlü vermesem bir türlü! Çünkü interface türden bağımsız olması gerekiyor. Örneğin:
  interface Foo(T) { ref T opCall(); }
 
  class Bar(T) : Foo!T {
    T x;
 
    this(T x) {
      this.x = x;
    }
    
    ref T opCall() {
      return x;
    }
  }
 
  import std.stdio;
 
void main() {
  Foo!uint[] foo;
 
  foo ~= new Bar!int(1);
  foo[0]().writeln;
  foo[0]() = 2;
  foo[0]().writeln;
 
  foo ~= new Bar!uint(1);
}
Yukarıda opCall() ile bir şeyler yapmayı başardım. Gel gör ki ikinci bir tür diziye girdiği zaman işler karışıyor. Bunu Foo!uint[] foo; satırındaki u harfini kaldırarak anlayabilirsiniz. Yani sadece int diye bir tür varsa ve biz uint'i türünde bir nesne eklersek doğal olarak son satıra hata atıyor. Bu sefer int'e çevirsek yukarıdaki satırlara uymuyor ve hata veriyor.

Bunun mutlaka çözümü vardır. Bakalım ilk kim bulacak...:)

Ama dilin geliştiricileri yeni sürüme basit bir özellik ekleyerek harikalar yapabilir. Yoksa D hack yapmamız icap ediyor ya da işaretçiler (pointers) ile kafayı yiyeceğiz. Bir yol daha aklıma geliyor ki o da türün işaretini ve boyutunu (sizeof)  yapıya yazıp başka bir sınıf ile sarma yapma. Şu an onun üzerine çalışıyorum. Gelişme olursa yazarım.

Başarılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #26
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
Bunun mutlaka çözümü vardır. Bakalım ilk kim bulacak...:)

OOP kullanan binlerce programcı biliyor zaten. :)

Ama dilin geliştiricileri yeni sürüme basit bir özellik ekleyerek

Önce mevcut olanakların yetersiz olduğunu ispatlamak gerek.

Burada yanıtlanması gereken şu: Bu nesnelerin toplu olarak türleri nedir ve bunlarla ne yapılır? Örneğin Kedi ve Köpek Hayvan'dır ve bütün Hayvan'lar sesÇıkart()'ır, beslen()'ir, vs. Veya program başka ne istiyorsa onu yapar.

Yani dosyadan taranan her veri "her türden" olamaz. Bir anlamı olmak zorundadır.

Ali
Avatar
Salih Dinçer #27
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Salih Dinçer:
Bunun mutlaka çözümü vardır. Bakalım ilk kim bulacak...:)

OOP kullanan binlerce programcı biliyor zaten. :)
Kim onlar...:)

Bu arada ilginç şeyler keşfettim! Ben değil, D'ciler, std.typecons modülünde harika ciciler yapmış:
import std.stdio, std.typecons, std.string;
 
        interface I { ref int opCall(); }
        static class A
        {
            public:
              size_t id = 1;
              
            abstract :
              ref int opCall();
              override string toString();
        }
        
        static class Foo: A, I {
          int t;
          this(int x) { t = x; }
          //ref int opCall() { return t; };
          //override  string toString() { return t.format; }
        }
        
        
        I[] test;
        {
            test ~= new BlackHole!Foo(10);
            test[0]()++;
            test[0]().writeln;
 
            test ~= new BlackHole!Foo(20);
            test[1]()++;
            test[1]().writeln;
            
            test ~= new BlackHole!Foo(30);
            test[2]()++;
            test[2]().writeln;
        }           
            test.writeln;
Şimdi bunun ne esprisi var diyebilirsiniz. Olay tamamen soyutlama (abstract) ile ilgili. Yani interface ile yetinmiyoruz bir de A isminde başka bir sınıf (bunu "static abstract class A" şeklinde de yazabilirdik!) ile soyut üyeleri parmağımızda oynatıyoruz. Bunu da BlackHole ismindeki şablonla yapıyoruz. Normalde o olmadan hata alıyoruz; isterseniz deneyin...:)

En iyisi mi fasülyenin faydasına (esprisine) geçelim. Biliyorsunuz sınıflar içinde bir toString işlevi vardır ama biz göremeyiz. Ne işe yarıyorsa artık. Mecburen işe yarasın diye override yaparız. Çünkü bizim üyelerimizi bilemiyor...:(

Neyse, ister tanımlı isterseniz tanımsız (hiç bir yerde kaşılığı) olmayan soyut üyeler tanımlayabiliyoruz. Eğer tanımlıysa ve siz bunu somut sınıfta karşılığını vermezseniz (örneğin yukarıdaki gibi toString satırını gizledim), bu soyut üye tanımlıyı bastırıyor. İşin bir güzeli de tıpkı interface'de olduğu gibi bir karşılığının akrabalarında (child) olması şart değil; yani:

Siz, eğer interface'de bir üye tanımlarsanız kalıtım yoluyla bunun bir karşılığını tanımlamanız gerekiyor. Abstract ile buna gerek yok. Bunu ise opCall işlevinin gizlendiğinden anlayabilirsiniz. Tabi soyut sınıfımız olan A'dakini de kaldırırsak interface ötmeye başlıyor, hani bana, hani bana diye...:)

Bir ilginç yanı da opCall'ın bir karşlığı olmadığı halde, soyut olan sınıf sayesinde statik bir şekilde somutlaştırılması. Çünkü yukarıdaki örneğin çıktısı "1\n2\n3\n" şeklinde. Bütün gizli satırları açarsanız da her şey düzgün çalışıyor.

Başka bir ilginç yan ise soyut olan sınıf içine somut bir public değer koyabilmem! Aslında A sınıfı, görünüşte sadece static bir sınıfmış gibi. Ama dedim ya abstract takısını da kullanabilirsiniz; bir fark yok. Aynı şekilde soyut değer de kullanabiliyorsunuz. Yani ilginç bir şekilde soyut ile somut üyeler bir arada. Hatta bu sınıfı tek başına da kullanabiliyorsunuz. Ben biraz renk katayım istedim.

:D
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #28
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Paylaştığın için teşekkürler. Gerçekten çok ilginç olanaklar. :)

Ali
Avatar
Salih Dinçer #29
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bu kadar mı! Belki de bu en anlamsız (abstract ~ soyut) olanıydı. Elimden geldiğince anlamdırmaya çalışmıştım ama şu Proxy mixin şablonuna ne demeli; ihtiyacınız olan her şeyi koyuyor oraya...:)
static struct tamSayı(T) { // byte, char, short hariç!
  private T value;
  mixin Proxy!value;
  this(T n){ value = n; }
}
  tamSayı!int s = 50;
  s >>= 1; // s = 25;
  s++; // s = 26;
  s /= 2; //s = 13; 
Orijinalinde sadece int verilmiş ve test edilmiş. Ancak bir kusuru var; tüm kesirli türlerde çalışmazken int ve long'da çalışıyor...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #30
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yaklaşık 30 iletinden sonra...

Artık konunun cevabını vereyim. Belki gelecekte birileri araştırdığında işine yarayacak. Ancak bu Zekeriya'nın tam olarak istediği değil sanırım. Öyle değil mi?

Maalesef farklı türler konusunda çok zorlandım. Belki önceki sayfada verdiğim çözüm ile tek tür (string) olarak ekrana yazabiliyoruz ama bunlar yönetmede (data management) başarılı olamadım. Belki de format() işlevi yerine bir şey koyarsak olabilir. Çünkü ekrana yansıyan veriler onun gözetmenliğinde geçiyordu. Neyse soruya gelelim:

Dizi içinde dizi kullanımı nasıl?
class içİçeDizi(T) {
    union {
      T     x; // tek değerli herhangi bir tür
      T[]   y; // tek boyutlu herhangi bir tür
      T[][] z; // iki boyutlu herhangi bir tür
    }
    T opIndex(T t) {
      x = t;
      return x;
    }
    T[] opIndex(T[] t...) {
      y = t;
      return y;
    }
    T[][] opIndex(T[][] t...) {
      z = t;
      return z;
    }
  }
 
  import std.stdio;
  alias size_t Tür;
  
void main() {
  içİçeDizi!Tür[3] dizi = new içİçeDizi!Tür; {
    "[".write;
    dizi[0][1].write(", ");
    dizi[1][1, 2].write(", ");
    dizi[2][[1, 2, 3], [3, 2, 1]].writeln("]");
  }
}// Çıktısı: [1, [1, 2], [[1, 2, 3], [3, 2, 1]]] 
Dediğim gibi, yukarıdaki koddan da anlaşılacak; aynı dizide farklı türler konusunda başarılı olamıyoruz. Belki bu konu OOP'un da üzerinde çünkü programlama dünyasının gerçekleri (türler ve birbirine dönüşümler!) yüzünden kısıtlanıyoruz. Elbette Python'da bir programlama dili ama zannedersem her şeyi tek bir tür olarak niteliyor. Bu ise yüksek bellek ihtiyacı ve yavaşlık olarak bizden bazı bedeller almasına neden oluyor.

Başka çözümü olan var mı?

Dip Not:
[1, [1, 2], [[1, 2, 3], [3, 2, 1]]] böyle bir sonucu elbette çok boyutlu bir diziyle alabilirdik ama her elemanın bellekte kaplayacağı alan en büyük elemanın içindeki dizinin elemanları kadar olacaktı.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 2 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-11-02, 03:02.
Değişiklik nedeni: Önemsiz, anlamı bozmayan yazım hatalarını düzelttim...
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  önceki  1  2  3  sonraki 
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 03:54:15 (UTC -08:00)