crypt of decay [entries|archive|friends|userinfo]
ketmar

[ userinfo | ljr userinfo ]
[ archive | journal archive ]

стало лучше! [May. 12th, 2017|12:51 pm]
[Tags|]

сократил время компиляции моей iv.vfs примерно вдвое (а иногда и больше).

раньше импорт std.stdio для writeln был ~240 мсек, а iv.vfs.io ~1100 мсек. теперь iv.vfs.io импортится за ~400 мсек. вполне.

импорт же цельной iv.vfs ничем не отличался от iv.vfs.io, а теперь — всего ~660 мсек.

поскольку iv.vfs умеет много гитик — типа прозрачного чтения файлов из разных архивов, — то я более-менее удовлетворён.

а секрет прострой: НАХУЙ ФОБОС! сильнее всего бил по яйцам std.datetime (который и нужен-то был только для того, чтобы конвертнуть зиповое время в unixtime, и время файла от дискового драйвера — который в большинстве случаев и не используется вовсе). и std.variant заодно заменил на намного более простую реализацию.
Linkmeow!

пилю тулкит [Jun. 14th, 2015|09:09 pm]
[Tags|]

подпилил объект стилей. раньше только так курить можно было:

ffkitStyle.setColor("background.active", "#fff");

а теперь ещё и так можно:

ffkitStyle.color.background.active = "#fff";

понятно, что все, идущее после color собирается в строку, и потом дёргается setColor с нужными аргументами. естественно, поля не предопределены, хоть color.hiu.pizda.jigurda пиши. читать тоже можно, причём ещё веселей:

string s = st.color.background.active; — ура, строка.
X11.Color c = st.color.background.active; — ура, иксовый цвет.

а в классе виджета то же самое будет последовательно дёргать стиль виджета (если есть), стиль родителя (если есть) и так далее до глобального стиля софтины. удобняшечка!
Link26 meows|meow!

великолепный мозголомный пиздец [Jun. 14th, 2015|06:49 am]
[Tags|]

мы имеем шаблоны, которые возвращают шаблоны, чтобы вы больше шаблоны!
struct foo {
  template opDispatch(string s) {
    T implementation(T) () if (is(T == int)) {
      return T.init+42;
    }
    T implementation(T) () if (is(T == string)) {
      return "wow";
    }

    alias opDispatch = implementation;
  }
}

void main() {
  foo f;
  int a = f.intprop!int;
  string s = f.intprop!string;
  import std.stdio;
  writeln(a); // 42
  writeln(s); // "wow"
}

fuckin' trickery!

зачем это надо? чтобы вместо f.intprop.get!string писать просто f.intprop!string.

трюк в том, что просто так вернуть результат шаблона как шаблон нельзя. обычно opDispatch пишут как eponymous template: int opDispatch(string s) () { return 42; } это то же самое, что и:
template opDispatch(string s) {
  int opDispatch () { return 42; }
}

сокращённая запись просто.

первым делом я подумал, что можно так:
struct foo {
  template opDispatch(string s) {
    T opDispatch(T) () { return T.init+42; }
  }
}

а вот те хуй! f.intprop!int даёт Error: no property 'intprop' for type 'foo'. это разворачивается внутри компилятора в конструкцию примерно такого типа: f.opDispatch!"intprop"!int(), и два «!» вводят его в ступор.

трюк в том, чтобы opDispatch возвращала отдельный шаблон, а не шаблонизированую функцию. тогда второй «!» превращается в первый, но для второго шаблона (ну да, вот такое вот понятное пояснение), и всё работает. но сделать просто return mytemplate нельзя: шаблон не функция, он не умеет ничего return. и вот тут‐то вступает в игру могучий alias, который хуй знает как, но работает.

на самом деле внутри всё ещё сложней выглядит (потому что в нерабочем варианте opDispatch тоже разворачивается в шаблон, и вся конструкция получается совершенно ебанутой), но этой дорогой ходить не надо, там в конце живёт дракон.

tbh, это не я придумал, этот трюк мне показал Adam D. Ruppe, очень хороший человек.

p.s. чувак в IRC долго эту хуйню наблюдал, а потом сказал: «вы все ёбнутые.»
Linkmeow!

про винты [Jun. 5th, 2015|11:03 pm]
[Tags|]

и про привинчивание. привинтил к дишечке вызов с именоваными параметрами. ну, как-то вот так (извините, тэги ставить лень):

void fuck (string ass, int dick);

fuck(ass:`wow`, dick:99);
// или так
fuck(dick:99, ass:`wow`);
// или вообще так
void fuck (string ass, int dick=146, bool tits=true);
fuck(tits:false, ass:`flabby`);

в общем-то, нужно не особо, но. но позволяет продолжать использовать bool заместо Flag. то есть, если раньше так:

void shit (Flag!`fast` doitfast);
shit(No.fast);

то теперь проще:

void shit (bool fast);
shit(fast: false);

делает не всё, что хотелось бы (есть хуйня с форвардингом в шаблонах), но меня устраивает и в таком виде.
Link6 meows|meow!

D, мультипоточная качалка [Apr. 1st, 2015|10:43 am]
[Tags|]

поскольку я иногда брутально выкачиваю всякие сайты (и нет, это не всегда порнуха), то автоматизирую я это дишечкой, понятно. и не секрет, что иногда выкачивать можно быстрее, если сначала построить список файлов, а потом сливать их несколькими потоками. по этому поводу я покажу вам, как удобно делается мультипоточная качалка на D.

код неполный, но представление о том, что я хочу показать, даст.
// ////////////////////////////////////////////////////////////////////////// //
import core.atomic;

__gshared string[] urlList; // it is protected by `synchronized`
shared usize urlDone;


void downloadThread (usize tnum, Tid ownerTid) {
  bool done = false;
  while (!done) {
    string url;
    usize utotal;
    receive(
      // usize: url index to download
      (usize unum) {
        synchronized {
          if (unum >= urlList.length) {
            // url index too big? done with it all
            done = true;
            cursorToInfoLine(tnum);
            write(«\r\e[0;1;31mDONE\e[0m\e[K»);
          } else {
            url = urlList[unum];
            utotal = urlList.length;
          }
        }
      },
    );
    // download file
    if (!done) {
      import std.exception : collectException;
      import std.file : mkdirRecurse;
      import std.path : baseName;
      string line;
      {
        import std.conv : to;
        line ~= to!string(tnum)~»: [«;
        auto cs = to!string(atomicLoad(urlDone)+1);
        auto ts = to!string(utotal);
        foreach (; cs.length..ts.length) line ~= ' ';
        line ~= cs~"/"~ts~"] "~nameNorm(url.baseName)~" ... ";
      }
      auto pbar = PBar2(line, atomicLoad(urlDone), utotal);
      int oldPrc = -1, oldPos = -1;
      auto conn = HTTP();
      conn.setUserAgent("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)");
      conn.onProgress = (scope usize dlTotal, scope usize dlNow, scope usize ulTotal, scope usize ulNow) {
        if (dlTotal > 0) {
          pbar.setTotal0(dlTotal);
          pbar[0] = dlNow;
        }
        synchronized {
          pbar[1] = urlDone;
          cursorToInfoLine(tnum);
          pbar.draw();
        }
        return 0;
      };
      collectException(mkdirRecurse(destDir));
      string fname = destDir~"/"~nameNorm(url.baseName);
      download(url, fname, conn);
    }
    // signal parent that we are idle
    ownerTid.send(tnum);
  }
}


// ////////////////////////////////////////////////////////////////////////// //
struct ThreadInfo {
  Tid tid;
  bool idle;
}

ThreadInfo[6] threads;


void startThreads () {
  foreach (immutable usize idx; 0..threads.length) {
    synchronized ++threadCount;
    threads[idx].idle = true;
    threads[idx].tid = spawn(&downloadThread, idx, thisTid);
  }
}


void stopThreads () {
  foreach (immutable usize idx; 0..threads.length) {
    threads[idx].idle = false;
    threads[idx].tid.send(usize.max); // 'stop' signal
  }
  for (;;) {
    usize idleCount = 0;
    foreach (ref trd; threads) if (trd.idle) ++idleCount;
    if (idleCount == threads.length) break;
    receive(
      (uint tnum) { threads[tnum].idle = true; }
    );
  }
}


// ////////////////////////////////////////////////////////////////////////// //
// и, в общем-то, фрагмент `main()`:
    writeln("downloading index page...");
    string page;
    {
      auto conn = HTTP();
      conn.setUserAgent("Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)");
      page = cast(string)get(pageURL, conn);
    }
    writeln("parsing page...");
    urlList = collectUrls(page);
    if (urlList.length == 0) {
      import core.exception : ExitException;
      writeln("FATAL: no urls found!");
      throw new ExitException();
    }
    destDir = getOutDir(urlList[0], pathPfx);
    if (!forceDown && destDir != "_down") {
      import std.file : exists;
      if (destDir.exists) {
        import core.exception : ExitException;
        writeln("ERROR: duplicate download: '", destDir, "'");
        throw new ExitException();
      }
    }
    writeln("downloading to '", destDir, "'...");
    startThreads();
    while (urlDone < urlList.length) {
      // find idle thread and send it url index
      usize tnum;
      for (;;) {
        for (tnum = 0; tnum < threads.length; ++tnum) if (threads[tnum].idle) break;
        if (tnum < threads.length) break;
        // no idle thread found, wait for completion message
        receive(
          (uint tnum) { threads[tnum].idle = true; }
        );
        // and try again
      }
      usize uidx = atomicLoad(urlDone);
      atomicOp!"+="(urlDone, 1);
      threads[tnum].idle = false;
      threads[tnum].tid.send(uidx);
    }
    // all downloads sheduled; wait for completion
    stopThreads();
    addProcessedUrl(pageURL);
    removeInfoLines();
    writeln(atomicLoad(urlDone), " images downloaded");

понятно, что можно не крутиться в цикле, занимаясь поиском бездельничающего потока, потому что мы и так в сообщении получаем его номер, и вообше код чуть почистить. но идея была не в этом, а в том, чтобы показать, как прельстиво делать такую фигню с message passing concurrency.

конечно, в стандартной библиотеке есть намного более продвинутые вещи для многопоточности: в принципе, можно было обойтись простым foreach по списку url и сгрузить остальное на автораспараллеливатель, но во-первых, я об этом забыл, а во-вторых, это выглядит не так заумно.
Link11 meows|meow!

блядская пидарасня [Feb. 9th, 2015|04:05 pm]
[Tags|, ]

нет, ёбаный нахуй, «давайте вынесем typedef в библиотечный шаблон, а из языка уберём в пизду» не катит. большой и сильный дядя Кэтмар заебался пытаться использовать недоёбаный говношаблон, поэтому вернул typedef на его законное место.

вообще, идея «раз мы кое-как, хуёво, криво и косо можем сделать это шаблоном — давайте нахуй из языка убирать» — дегенеративная идея. особенно дегенеративно выглядит «обоснование» убирания typedef: оно, видите ли, не всегда работает, как должно.

блядь, ваш ёбаный шаблон ВСЕГДА работает как не должен! всегда хуёво, всегда неправильно, всегда уебанистически. а прельстивый typedef для всех моих случаев работает просто заебись как отлично.
Linkmeow!

михалкова D тоже не любит [Dec. 6th, 2014|05:36 am]
[Tags|]

import std.stdio;

string text = "mihalkov";

class A {
  import std.conv;
}

class B : A {
  void yoba () {
    writeln(text);
  }
}

void main () {
  auto b = new B();
  b.yoba();
}
Linkmeow!

чуть-чуть про D [Dec. 5th, 2014|04:01 am]
[Tags|]

вот вы не знаете, а на самом деле язык D стоит на страже нравственности! как? вот вам пример кода:
void pit (string text) {
import std.stdio;
import std.conv;
writeln(text);
}

void main () {
pit("fuck me in my ass!");
}

казалось бы, пидарасы! ан нет, суровый компилятор D бдит, и эта программа выводит пустую строку, а не противоествественный содомический призыв!
Link5 meows|meow!

dевиации [Oct. 8th, 2014|11:17 pm]
[Tags|]

запомните, ромашки: даже если вам очень-очень хочется написать static if (__ctfe), этого делать не надо. надо писать if (__ctfe). потому что static if вычисляется во время компиляции, а цтфе ли оно, компилятор узнаёт только во время выполнения.

не переживайте, для нормального вызова это превращается в if (0), а такую хуйню компилятор умеет убирать ещё где-то после стадии семантического анализа.

я к чему? я к тому, что постоянно хочу туда впихуить этот самый static. настолько, что уже почти созрел научить компилятор ругаться на это непотребство.

кстати, о воронах. уж месяц на исходе, а герман всё в запое я всё жду: заметит ли кто-нибудь, что я таки выполнил bounty task аж на целых два десятка и ещё пять американских денег? и что будет с тем, кто его выполнит вторым, когда я предъявлю патч в багзилле? суды, разборки, адвокаты, проданые дома и сломаные жизни…
Link8 meows|meow!

navigation
[ viewing | most recent entries ]