Zkušenosti s jazykem D

Kozzi

Re:Zkušenosti s jazykem D
« Odpověď #45 kdy: 25. 02. 2014, 16:07:52 »
No, teď se pokouším vytvořit vlastní object pool (uskladňuje a alokuje objekty pomocí malloc a free místo vestavěného GC). Teda celkem mordor, funguje ale ... jen díky pomoci na fóru a knihovním funkcím (!!). Z toho mě ale chytá rapl ... když bych chtěl v D dělat něco low level, nemůžu používat std knihovnu když si ji neportuju a právě takový object pool je dobrej jenom když dělám něco low level. D je tak jedině dobrý jako high level lang. Low level nikdy ... pak je to celkem pěknej jazyk. Někdy rychlejší než C++.

To je to co jsem psal, proste pro low level to neni idealni. Ono ne ze by to neslo, ale ve vysledku si stim clovek zas moc oproti C nebo C++ nepomuze. Zejmena proto ze vetsina dobrych vlastnosti jazyka je zavisla na GC. Ja jazyk D pouzivam proste tam kde bych pouzil C++, ale kde se nejedna vylozene o low level. Napriklad nastroj pro zpracovani binarnich dat s gps jednotek a jejich ulozeni do databaze. Ale pro napsani ovladace pro operacni system bych to nepouzil.

Ale jak jiz bylo uvedeno problem s low level a obecne s gc je priorita cislo jedna pro tento rok. Takze se da ocekavat zlepseni. Dokonce vznikly navrhy i na vznik jazyka D pro low level http://forum.dlang.org/thread/lddug4$jgv$1@digitalmars.com


Kozzi

Re:Zkušenosti s jazykem D
« Odpověď #46 kdy: 25. 02. 2014, 16:14:27 »
Jinak jako mozne pole pusobnosti bych pro jazyk D videl psani mobilnich aplikaci. Protoze psani mobilnich aplikaci v C++ mi neprijde proste zrovna idealni, psani v Jave je sice celkem fajn, ale celkova vykonost aplikaci na androidu a naroky na systemove pozadavky hovori za vse. V tomto smeru bych jazyk D prirovnal ObjectiveC pro IOS

RAII

Re:Zkušenosti s jazykem D
« Odpověď #47 kdy: 25. 02. 2014, 16:31:41 »
D verze pro low level. Já netuším čím myslej. Sice nejsem žádnej hyper super máster, to ne. Ale vím jak upravit Dčko aby bylo použitelný. Všechny featury a celou STD knihovnu předělat na malloc/free model. Dále vytvořit operátor gnew (alokace GC) a mnew (malloc) a mdelete (free). Přičemž mnew a mdelete by šlo přetížit ve třídě + možnost globálního předefinovaní mnew a mdelete (jako v C++). Pak bych sral na C++ a šel do toho, jenže teď? Teď je to peklo. Ani konstruktor nezavoláš správně bez STD knihovny. Jo, a znormálnit volání konstruktorů a destruktorů aby nebylo třeba hrabat do knihovny. Co sem si všim tak vlastní volání __ctor či __dtor funguje, ale zpětně potom někde schytám SIGSEGV. No vlastně ne. Ani by nemuseli upravovat volání konstruktorů a destruktorů, to by si ošefovali operátory dynamické alokace (jako v C++ ...).

RAII

Re:Zkušenosti s jazykem D
« Odpověď #48 kdy: 25. 02. 2014, 16:34:32 »
Jinak range operátory sou úžasný. A někde sem viděl benchmark ve kterym bylo Dčko výrazně rychlejší než C++ (?~30%).

RAII

Re:Zkušenosti s jazykem D
« Odpověď #49 kdy: 25. 02. 2014, 16:39:29 »
Jo zapomněl sem napsat, vytvořit uživatelem předefinovatelný alokátor pro GC. Aby bylo možné třeba vytvořit ňejaký pool statické paměti a na ní napojit GC. Sice nevím k čemu by to bylo, ale šlo by vytvořit snadno low level program s GC (ačkoli by to pak bylo zkurveně pomalí -> ale zajímaví).


Re:Zkušenosti s jazykem D
« Odpověď #50 kdy: 25. 02. 2014, 16:46:12 »
Jo zapomněl sem napsat, vytvořit uživatelem předefinovatelný alokátor pro GC. Aby bylo možné třeba vytvořit ňejaký pool statické paměti a na ní napojit GC. Sice nevím k čemu by to bylo, ale šlo by vytvořit snadno low level program s GC (ačkoli by to pak bylo zkurveně pomalí -> ale zajímaví).
To tusim ide pomocou GC.malloc: http://dlang.org/phobos/core_memory.html#.GC.malloc
Skus sa pozret aj sem: https://github.com/andralex/phobos/blob/allocator/std/allocator.d

Das sem kod tvojho object poolu?

RAII

Re:Zkušenosti s jazykem D
« Odpověď #51 kdy: 25. 02. 2014, 17:28:35 »
module test.main;
import std.stdio;
import std.c.stdlib;
import std.traits;
import std.random;
import std.conv;

class example
{
   int num;
   this()
   {
      writeln("example ctor");
      num = 1000;
   }
   ~this()
   {
      writeln("example dtor");
   }
   int callee()
   {
      return num*2;
   }
}

struct simpleVector(T)
{
    enum instanceSize = __traits(classInstanceSize, T);
    enum padding = instanceSize % std.traits.classInstanceAlignment!T;
    enum paddedInstanceSize = instanceSize + padding;
    byte * buffer = null;
    int size = 0;
    this(int _size)
    {
        size = _size;
        buffer = cast(byte*)malloc(paddedInstanceSize*size);
        for (int i=0; i<size;++i)
        {
            emplace!T(buffer[i*paddedInstanceSize .. (i+1)*paddedInstanceSize]);
        }
    }
    ~this()
    {
        for (int i=0; i<size;++i)
        {
           dtor(cast(T)(buffer+i*paddedInstanceSize));
        }
        size = 0;
        free(buffer);
    }
   T opIndex(int index)
   {
      return cast(T)(buffer+index*paddedInstanceSize);
   }
    void dtor(T ob)
    {
        ob.__dtor();
    }
}

void main()
{
   simpleVector!example vc = simpleVector!example(5);
   auto gen = Random(unpredictableSeed);   
   for (int i=0; i<vc.size; ++i)
   {
      vc.num = uniform(0,1024,gen);
   }
   for (int i=0; i<vc.size; ++i)
   {
      write(vc.num);
      write(" -> ");
      writeln(vc.callee());
   }      
}

RAII

Re:Zkušenosti s jazykem D
« Odpověď #52 kdy: 25. 02. 2014, 17:33:22 »
Ale bez pomoci bych to fakt nedal. Pokoušel sem se nahradit knihovní funkci emplace svojí verzí, končí to tím že když zavolám funkcí pod uloženým objektem, vyhodí mi to SIGSEGV.

void ctor(T ob)
{
   ob.__ctor();
}

Inu, zřejmě to není jen o tom konstruktoru, ta konstrukce objektu ...
BTW, neví tady někdo jak zabránit DMD kompileru v připojení systémových knihoven a dalších kravin (i GC!). Kdyby to bylo GDC tak bych dal -nostdlib, ale GDC mi ňák nefachčilo.

RAII

Re:Zkušenosti s jazykem D
« Odpověď #53 kdy: 25. 02. 2014, 17:36:46 »
Z příspevku mi to odpálilo hranaté závorky. Mají být v obou cyklech ve funkci main. logika napoví kde.

RAII

Re:Zkušenosti s jazykem D
« Odpověď #54 kdy: 25. 02. 2014, 17:40:26 »
GC.malloc nemění alokátor ale pouze si u GC vynutí požadovaný počet bajtů jež de pak vrátit GC.free. Takže na nic (máme operátor new ... a delete pokud ho nestihli zrušit).

Kozzi

Re:Zkušenosti s jazykem D
« Odpověď #55 kdy: 25. 02. 2014, 19:12:36 »
Ale bez pomoci bych to fakt nedal. Pokoušel sem se nahradit knihovní funkci emplace svojí verzí, končí to tím že když zavolám funkcí pod uloženým objektem, vyhodí mi to SIGSEGV.

void ctor(T ob)
{
   ob.__ctor();
}

Inu, zřejmě to není jen o tom konstruktoru, ta konstrukce objektu ...
BTW, neví tady někdo jak zabránit DMD kompileru v připojení systémových knihoven a dalších kravin (i GC!). Kdyby to bylo GDC tak bych dal -nostdlib, ale GDC mi ňák nefachčilo.

a co toto:

void ctor(T ob)
   {
      byte[] chunk = (cast(byte*)ob)[0 .. instanceSize];
      chunk = T.classinfo.init[];
      ob.__ctor();
}

RAII

Re:Zkušenosti s jazykem D
« Odpověď #56 kdy: 25. 02. 2014, 19:28:27 »
Perfektní (šlape jak má), z jakého důvodu nestačí proboha zavolat jen konstruktor ? Jinak byte[] je dynamické pole jež je závislé na GC takže s tímhle fakt jako v bootloaderu nemůžu machrovat. Jednu věc nechápu. byte[] chunk = (cast(byte*)ob)[0 .. instanceSize]; překopíruje bajt po bajtu obsah objektu ob do pole chunk. Poté pomocí T.classinfo.init získáme statickou inicializaci jež překopírujeme do chunku. No jo ale ob je netknutý když nad ním volám konstruktor. Tak jak to že to funguje? Co mě v D mate jsou reference. V C++ jsou takové pěkné čisté a vlastně s nimi vůbec nepracujeme (maximálně v argumentech).

Re:Zkušenosti s jazykem D
« Odpověď #57 kdy: 25. 02. 2014, 19:31:06 »
...

Vector by mohol vyzerat takto (bez emplace/destroy):
Kód: [Vybrat]

import std.stdio;

class example{
int num;

this(int num){
this.num = num;
writeln("example ctor ", num);
}
~this(){
writeln("example dtor ", num);
}
}

struct simpleVector(T)if(is(T == class)){
import core.stdc.stdlib, std.traits;

enum instanceSize = __traits(classInstanceSize, T);
enum padding = instanceSize % std.traits.classInstanceAlignment!T;
enum paddedInstanceSize = instanceSize + padding;

private void[] buffer;
private size_t size_ = 0;

private T data(size_t i){
return cast(T) buffer[i*paddedInstanceSize .. $].ptr;
}

@property size_t size()const{return size_;}

bool emplaceBack(Args...)(Args args){
if(size*paddedInstanceSize < buffer.length){
auto s = buffer.length*2;
auto p = cast(ubyte*) realloc(buffer.ptr, s);
if(!p)return false;
buffer = p[0 .. s];
}
data(size_++).__ctor(args);
return true;
}

void clear(){
for(size_t i=0; i < size; ++i){
data(i).__dtor();
}
size_ = 0;
}

@disable this();

static auto opCall(){
return simpleVector(2);
}

this(size_t x){
assert(x);
auto bytes = paddedInstanceSize*x;
auto p = malloc(bytes);
buffer = p ? p[0 .. bytes] : null;
}

~this(){
for(size_t i=0; i < size; ++i){
data(i).__dtor();
}
free(buffer.ptr);
}

T opIndex(size_t index){
assert(index < size);
return data(index);
}
}

void main(){
auto vc = simpleVector!example();
foreach(int i; 0..10){
vc.emplaceBack(i);
}

foreach(size_t i; 0..5){
vc[i*2].num *= 10;
}   

for (int i=0; i<vc.size; ++i){
writeln(vc[i].num);
}     
}


Kozzi

Re:Zkušenosti s jazykem D
« Odpověď #58 kdy: 25. 02. 2014, 19:51:09 »
Perfektní (šlape jak má), z jakého důvodu nestačí proboha zavolat jen konstruktor ? Jinak byte[] je dynamické pole jež je závislé na GC takže s tímhle fakt jako v bootloaderu nemůžu machrovat. Jednu věc nechápu. byte[] chunk = (cast(byte*)ob)[0 .. instanceSize]; překopíruje bajt po bajtu obsah objektu ob do pole chunk. Poté pomocí T.classinfo.init získáme statickou inicializaci jež překopírujeme do chunku. No jo ale ob je netknutý když nad ním volám konstruktor. Tak jak to že to funguje? Co mě v D mate jsou reference. V C++ jsou takové pěkné čisté a vlastně s nimi vůbec nepracujeme (maximálně v argumentech).

Tak zaprve dynamicke pole samo osobe neni zavisle na GC, je to jenstruktura uchovavajici velikost pole a adresu na data. to co vyzaduje GC je napriklad az konkatenace poli atd. Takze to problem neni.

Jinak ob je v podstate reference (v podstate si predstav ze v D se pokazde jedna o ekvivalent k C++ referenci), to znamena ze tim castem na byte* z toho udelam pointer na byte. Potom pomoci slice operatoru vytvorim pole bytu s velikost instanceSize. Jinak jde o to ze objekt v D ma na zacatku v pmaeti strukturu TypeInfo_Class. No a ta musi byt pravne nainicializovana jinak nemuzes volat konstruktor.

RAII

Re:Zkušenosti s jazykem D
« Odpověď #59 kdy: 25. 02. 2014, 20:15:37 »
To kozzi: Jo, dobrý už vím jak to že to funguje. To vitamin: máš to řešení pěkný. Jaks to vohackoval? Nikde tam nevidím T.classinfo.init. Jak je tam staticky inicializován objekt? Je tam jen volání __ctor().