...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

DFL

だいたいShooさんのPull Requestです。

DFL64はビルドがうまくいかなくて検証できず。

DFL for dmd 2.066

久しぶり。

import dfl;

pragma(lib, "dfl.lib");

class MainForm : Form {
	private Button _button;
	private ListBox _listbox;
	private MainMenu _menu;
	
	this() {
		_button = new TestButton();
		_button.text = "ok";
		_button.parent = this;
		_button.location = Point(100, 100);
		
		_listbox = new ListBox();
		_listbox.parent = this;
		_listbox.size = Size(60, 150);
		_listbox.items.add("foo");
		_listbox.items.addRange(["hoge", "piyo"]);
		_listbox.click ~= (Control c, EventArgs ea) { msgBox(_listbox.selectedItem.toString()); };
		
		_menu = new MainMenu();
		MenuItem item = new MenuItem();
		item.text = "File";
		MenuItem subItem = new MenuItem();
		subItem.text = "Open";
		auto menuClickHandler = (MenuItem mi, EventArgs ea){ msgBox("open the door"); };
		subItem.click ~= menuClickHandler;
		item.menuItems.add(subItem);
		_menu.menuItems.add(item);
		this.menu = _menu;
	}
}

class TestButton : Button {
	override void onClick(EventArgs ea) { // delegateでもoverrideでもおk
		msgBox("hi");
	}
}

void main() {
	Application.run(new MainForm());
}

=>

あけおめ.

import std.stdio;

int f(alias F)(int x)
{
	return F(x);
}

int g(int delegate(int) dg, int x)
{
	return dg(x);
}

int h(int function(int) dg, int x)
{
	return dg(x);
}

void main()
{
	writeln(f!(x => x + 1)(1));
	writeln(g(x => x + 1, 1));
	writeln(h(x => x + 1, 1));
}

これが動くようになりました.
パッチが適用されるのが早い!

愚直に書くのが最速だった

final class Lexer
{
	private const string source;
	
	this(in string source)
	{
		this.source = source;
	}
	
	const(string)[] lex() const
	{
		static string[] f(string line)
		{
			auto app2 = appender!string();
			app2.put(line);
			app2.put(",");
			app2.put(TOKEN_END_OF_LINE_MARK);
			return split(app2.data, ",");
		}
		
		auto app = appender!(string[])();
		foreach (string line; splitLines(source))
			foreach (string r; f(line))
				app.put(r);
		return app.data;
	}
}

std.parallelismやThreadを使って書くよりも愚直にforeachで書く方が早かった.
むむむ.

何だかうまく書けない

final class Lexer
{
	class LexerThread : Thread
	{
		private const(string)[] lines;
		private Appender!(string[]) app;
		
		this(const(string)[] lines)
		{
			this.lines = lines;
			app = appender!(string[])();
			app.reserve(10000);
			super(&run);
		}
		
		void run()
		{
			foreach (line; lines)
			{
				auto app2 = appender!string();
				app2.put(line);
				app2.put(",");
				app2.put(TOKEN_END_OF_LINE_MARK); // "[TEOL]"
				app.put(split(app2.data, ","));
			}
		}
		
		string[] data() @property
		{
			return app.data;
		}
	}
	
	private const string source;
	
	this(in string source)
	{
		this.source = source;
	}
	
	const(string)[] lex() const
	{
		const(string)[] lines = splitLines(source);
		auto worker1 = new LexerThread(lines[    0 .. $/4*1]);
		auto worker2 = new LexerThread(lines[$/4*1 .. $/4*2]);
		auto worker3 = new LexerThread(lines[$/4*2 .. $/4*3]);
		auto worker4 = new LexerThread(lines[$/4*3 .. $    ]);
		worker1.start();
		worker2.start();
		worker3.start();
		worker4.start();
		worker1.join();
		worker2.join();
		worker3.join();
		worker4.join();
		auto app = appender!(string[])();
		app.put(worker1.data);
		app.put(worker2.data);
		app.put(worker3.data);
		app.put(worker4.data);
		return app.data;
	}
}

何がLexerなのか全然分からないけどそれは脇に置いておく.
linesへ1行ごとに格納して,それを4分割して4つのスレッドに処理を任せて,最後にapp.dataとして直列化する.
何かこういうことするにはsharedはいらないみたいだ.
もっとまともな書き方がありそうに思えるけど特に思いつくわけでもなく・・・.