September 15, 2012

Ben de hemen hemen aynı yaptım. (Aslında önce Task nesneleriyle bolca debelenmiştim de. :)) Seninki gibi 'auto kb = new T[][2];' yapmak yerine ben aşağıdakini denemiştim. Daha kısa:

foreach (parça; parallel([ küçük, büyük ]))

Ben de daha hızlı sonuç elde edemedim. Herhalde context switching'in bedelini ödüyoruz. (?)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 16, 2012

Dizilerin .sort'u da qsort kullanıyormuş:

https://github.com/D-Programming-Language/druntime/blob/master/src/rt/qsort.d

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Teşekkürler ama kodu derlediğim halde çalıştıramadım. Mutlaka veriyi doğru bir şekilde vermiyor olmalıyım...:)

private TypeInfo ti;

void main() {
 auto dizi = [5, 3, 25, 6, 17, 1, 2, 18, 8];
 dizi.writeln;
 writeln(qsort(&dizi));
}

void[] qsort(T)(T[]* a) {
 byte*[40] stackbuf = void; // initial stack buffer
 auto stack = stackbuf[0..$]; // stack
 auto sp = stack.ptr; // stack pointer
 auto width = ti.tsize();
 auto base = cast(byte *)a.ptr;
 const int _maxspan = 7;
 auto thresh = _maxspan * width; // size of _maxspan elements in bytes
 auto limit = base + a.length * width; // pointer past end of array
 while(true) { // repeat until done then return
   while(limit - base > thresh) { // if more than _maxspan elements
     ti.swap((cast(uint)(limit - base) >> 1) -
           (((cast(uint)(limit - base) >> 1)) % width) + base, base);
         //swap middle, base
     auto i = base + width; // i scans from left to right
     auto j = limit - width; // j scans from right to left

     if(ti.compare(i, j) > 0) ti.swap(i, j); // Sedgewick's three-element sort
     if(ti.compare(base, j) > 0) ti.swap(base, j); // sets things up so that
     if(ti.compare(i, base) > 0) // *i <= *base <= *j
       ti.swap(i, base); // *base is the pivot element

     while(true) {
       do i += width; while (ti.compare(i, base) < 0); // move i right until *i >= pivot
       do j -= width; while (ti.compare(j, base) > 0); // move j left until *j <= pivot
       if(i > j) break; // break loop if pointers crossed
       ti.swap(i, j); // else swap elements, keep scanning
     }
     ti.swap(base, j); // move pivot into correct place
     if(j - base > limit - i) { // if left subarray is larger...
       sp[0] = base; // stack left subarray base
       sp[1] = j; // and limit
       base = i; // sort the right subarray
     } else { // else right subarray is larger
       sp[0] = i; // stack right subarray base
       sp[1] = limit; // and limit
       limit = j; // sort the left subarray
     }
     sp += 2; // increment stack pointer
     if(sp == stack.ptr + stack.length) {
       // Double the size of stack[]
       auto newstack = cast(byte**)
            core.stdc.stdlib.alloca(stack.length * 2 * (*sp).sizeof);
       newstack[0..stack.length] = stack[];
       sp = &newstack[stack.length];
       stack = newstack[0..stack.length * 2];
     }
   }

   // Insertion sort on remaining subarray
   auto i = base + width;
   while (i < limit){
     auto j = i;
     while (j > base && ti.compare(j - width, j) > 0) {
       ti.swap(j - width, j);
       j -= width;
     }
     i += width;
   }

   if (sp > stack.ptr) {} // if any entries on stack...
     sp -= 2; // pop the base and limit
     base = sp[0];
     limit = sp[1];
   }
   //else // else stack empty, all done
   return *cast(void[]*)(&a);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Şimdi de başka bir kütüphanede aynı algoritmanın biraz daha derlenip toplanmışl halini denedim sonuç aynı:
'
[5, 3, 25, 6, 17, 1, 2, 18, 8]
object.Error: Access Violation
'

private TypeInfo ti;
struct Array {
   size_t length;
   byte* data;
}

void main() {
 byte[] dizi = [5, 3, 25, 6, 17, 1, 2, 18, 8];
 dizi.writeln;
 Array veri = Array(dizi.length, dizi.ptr);
 writeln(qsort(veri));
}

Array qsort(Array a) {
 static const uint Qsort_Threshold = 7;

 struct StackEntry {
   byte *l;
   byte *r;
 }

 size_t elem_size = ti.tsize();
 size_t qsort_limit = elem_size * Qsort_Threshold;

 static assert(ubyte.sizeof == 1);
 static assert(ubyte.max == 255);

 StackEntry[size_t.sizeof * 8] stack; // log2( size_t.max )
 StackEntry * sp = stack.ptr;
 byte* lbound = cast(byte *) a.data;
 byte* rbound = cast(byte *) a.data + a.length * elem_size;
 byte* li = void;
 byte* ri = void;

 while (1) {
   if (rbound - lbound > qsort_limit) {
     ti.swap(lbound, lbound + (
           ((rbound - lbound) >>> 1) -
           (((rbound - lbound) >>> 1) % elem_size)));

     li = lbound + elem_size;
     ri = rbound - elem_size;

     if (ti.compare(li, ri) > 0) ti.swap(li, ri);
     if (ti.compare(lbound, ri) > 0) ti.swap(lbound, ri);
     if (ti.compare(li, lbound) > 0) ti.swap(li, lbound);

     while(true) {
       do li += elem_size; while (ti.compare(li, lbound) < 0);
       do ri -= elem_size; while (ti.compare(ri, lbound) > 0);
       if (li > ri) break;
       ti.swap(li, ri);
     }
     ti.swap(lbound, ri);
     if(ri - lbound > rbound - li) {
       sp.l = lbound;
       sp.r = ri;
       lbound = li;
     } else {
       sp.l = li;
       sp.r = rbound;
       rbound = ri;
     }
     ++sp;
   } else {
     // Use insertion sort
     for(ri = lbound, li = lbound + elem_size;
        li < rbound;
        ri = li, li += elem_size) {
       for( ; ti.compare(ri, ri + elem_size) > 0; ri -= elem_size) {
         ti.swap(ri, ri + elem_size);
         if(ri == lbound) break;
       }
     }
     if(sp != stack.ptr) {
       --sp;
       lbound = sp.l;
       rbound = sp.r;
     } else return a;
   }
 }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Direkt dizilerin .sort olanağını kullanmaya ne dersin:

import std.stdio;
import std.array;

void main()
{
   int a[] = new int[10];

   a[0] = 23;
   a[1] = 1;
   a[2] = 64;
   a[3] = 5;
   a[4] = 6;
   a[5] = 5;
   a[6] = 17;
   a[7] = 3;
   a[8] = 0;
   a[9] = -1;

   a.sort;

   for (int i = 0; i < a.length - 1; i++)
   {
       // printf("i = %d", i);
       printf(" %d %d\n", a[i], a[i + 1]);
       assert(a[i] <= a[i + 1]);
   }

   auto b = new uint[0xFF_FFFF];
   b.sort;
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Alıntı (erdem):

>

Direkt dizilerin .sort olanağını kullanmaya ne dersin:
Sıralama olanağının içeriğinde değişiklik yapıp bir şeyler kapmaya çalışıyorum...

Alıntı (acehreli):

>

Yukarıda if satırındaki {} bütün olayı bozmuş tabii.
Düzenleme yaptığım sırada Sublime Text 2 autocomplete yapmış olmalı...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Teşekkür hocam, ben de şuradaki türlere bakıyordum:

https://github.com/D-Programming-Language/druntime/tree/master/src/rt/typeinfo

Demek ki türü belirtmediğimiz için null gidiyor, çok çok teşekkürler...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Çok çok amatörce (fazla yerini karıştırmadan) sadeleştirdim...:)

Farklı türlerde kullanabilmek için işlev şablonu kullandım ama küçük bir yerde bir püf noktası olmalı ki byte harici çalışmıyor. Oysa bunu TypeInfo sınıfından kurtartmadan önce de denemiştim...

void main() {
 byte[] dizi = [5, 3, 25, 6, 17, 1, 2, 18, 8];
 dizi.writeln;
 qsort(dizi);
 dizi.writeln;
}

void qsort(T)(ref T[] a) {
 struct Stack(T) {
   T*[] l, r;
   size_t konum;

   void push(T)(T* left, T* right) {
       l ~= left;
       r ~= right;
       konum++;
   }

   void pop(T)(ref T* left, ref T* right) {
       konum--;
       left = l[konum];
       right = r[konum];
   }

   bool empty() const {
       return konum == 0;
   }
 }
 void swap(T* p1, T* p2) {
   T temp = *cast(T*)p1;
            *cast(T*)p1 = *cast(T*)p2;
            *cast(T*)p2 = temp;
 }
 size_t elem_size = T.sizeof;
 size_t qsort_limit = elem_size * 7; //ti.tsize() * Qsort_Threshold ;
 Stack!T sp;

 T* lbound = a.ptr;
 T* rbound = a.ptr + a.length * elem_size;
 T* li, ri;

 while(true) {
   if(rbound - lbound > qsort_limit) {
      swap(((rbound - lbound) >> 1) -
           ((rbound - lbound) >> 1) % elem_size + lbound, lbound);

     li = lbound + elem_size;
     ri = rbound - elem_size;

     if((*li - *ri) > 0) swap(li, ri);
     if((*lbound - *ri) > 0) swap(lbound, ri);
     if((*li - *lbound) > 0) swap(li, lbound);

     while(true) {
       do li += elem_size; while ((*li - *lbound) < 0);
       do ri -= elem_size; while ((*ri - *lbound) > 0);
       if(li > ri) break;
       swap(li, ri);
     }

     swap(lbound, ri);

     if(ri - lbound > rbound - li) {
       sp.push(lbound, ri);
       lbound = li;
     } else {
       sp.push(li, rbound);
       rbound = ri;
     }
   } else {
     for(ri = lbound, li = lbound + elem_size;
        li < rbound;
        ri = li, li += elem_size) {

       for(auto t = *ri - *(ri + elem_size);
                t > 0; ri -= elem_size) {
         swap(ri, ri + elem_size);
         if(ri == lbound) break;
         t = *ri - *(ri + elem_size);
       }
     }
     if(!sp.empty) sp.pop(lbound, rbound);
     else break;
   }
 }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

Salih, kodu kopyalarken bir gariplik olmuş herhalde. dmd şuradaki return satırına hiç gelinemeyeceğini söyledi:

   if (sp > stack.ptr) {} // if any entries on stack...
     sp -= 2; // pop the base and limit
     base = sp[0];
     limit = sp[1];
   }
   //else // else stack empty, all done
   return *cast(void[]*)(&a);

Yukarıda if satırındaki {} bütün olayı bozmuş tabii.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 18, 2012

İkinci programın sorununu buldum. dmd'ye -g seçeneğini verdim ve programı gdb altında çalıştırdım. Şu satırda patladı:

 size_t elem_size = ti.tsize();

Çünkü ti null. D runtime'ın kodundaki ti ise işleve yukarıdan veriliyor. Mecbursak bu kodu şöyle işletebiliriz:

Array qsort(Array a) {
TypeInfo ti = typeid(byte.init);  // <-- ti'yi qsort'un içine aldım.
                                  //     Dikkat: Bu haliyle yalnızca 'byte'
                                  //     ile doğru çalışır.

Sıralanmış sayıları görmek için de şu:

 Array sonuç = qsort(veri);

 foreach (i; 0 .. sonuç.length) {
     writeln(sonuç.data[i]);
 }

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]