Профилируем FMS приложение

Tags:

Начнем с оффтопика. Надо сказать, что для разработки под FMS есть довольно мало тулов и библиотек. Практически ничего нет.

Это, в общем-то, понятно -- мало кто пишет какую-то серьезную серверную логику под FMS. Это, все таки, медиа сервер, а не сервер приложений. И мы сейчас тоже уходим от того, чтобы писать много кода под FMS.

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

И сейчас будет небольшой тул для профилирования.

Увы, для профилирования расхода памяти никаких средств нет. Но мне это и не нужно было, а нужно было профилирование по времени выполнения кода. С этим проще. Для этого ничего особо не нужно, кроме как засекать моменты времени до и после выполнения определенного участка кода и сравнивать их. Но нужно сделать это удобно, чтобы обойтись минимумом кода. И у меня получился такой класс:


// core/Profiler.asc

Profiler = {};
Profiler.active = false; 
Profiler._marks = {};

Profiler.begin = function()
{
	if(!this.active) return;

	return new Date;
}

Profiler.end = function(mark/*String*/, begin/*Date*/)
{
	if(!this.active) return;

	this.add(mark, begin, new Date);
}

Profiler.add = function(mark/*String*/, begin/*Date*/, end/*Date*/)
{
	if(!this.active) return;

	end/*Number*/ = end.valueOf();
	begin/*Number*/ = begin.valueOf();

	if(!this._marks[mark]) this._marks[mark] = [];

	var values/*Array*/ = this._marks[mark];
	values.push(end > begin ? end - begin : begin - end);
}

Profiler.getStat = function()
{
	var res = " ## Profiler stat:\n";
	for(var mark in this._marks)
	{
		var values = this._marks[mark];
		if(values.length == 0) continue;

		var min = Number.MAX_VALUE;
		var max = 0;
		var sum = 0;
		for(var i in values)
		{
			var val = values[i];
			min = Math.min(min, val);
			max = Math.max(max, val);
			sum += val;
		}
		res += " ## [" + mark + "]"
				+ " max:" + max
				+ " min:" + min
				+ " average:" + (sum / values.length)
				+ " total:" + values.length + "\n";

	}
	res += " ## \n";
	return res;
}

Profiler.traceStat = function()
{
	trace(this.getStat());
}

Класс небольшой и достаточно очевидный. Чтобы его использовать, нужно его подключить и активировать:


load("core/Profiler.asc");
Profiler.active = true;

И потом можно окружать нужные участки кода такой штукой:


var begin = Profiler.begin;
// some code
Profiler.end("myMark", begin);

var begin = Profiler.begin;
// some other code
Profiler.end("myOtherMark", begin);

Предполагается, что эти участки кода будут проходиться много раз, при каждом прохождении будет сохраняться его время. Но потом нам нужно как-то поглядеть результаты. Их можно сохранять в файл, или просто выводить в консоль по определенному событию. Или даже просто через какой-то интервал с помощью Profiler.traceStat();

Статистика будет выглядеть вот так:

 ## Profiler stat:
 ## [onConnect] max:49 min:0 average:0.4895972363978959 total:63685
 ## [onDisconnect] max:33 min:0 average:0.051186056754546023 total:63572
 ## [NotifyUpdaters] max:1 min:0 average:0.06069094304388422 total:2142
 ## [CheckUpdaterConnections] max:24 min:0 average:6.1477272727272725 total:352
 ## [CheckKeepAlive] max:18 min:0 average:4.96875 total:352
 ## [StartSession] max:2 min:0 average:0.25411061285500747 total:669
 ## [CreateInvitation] max:9 min:0 average:0.2880859375 total:1024
 ## [SendTyping] max:40 min:0 average:0.07970135919851956 total:31342
 ## [SendMessage] max:1 min:0 average:0.12403100775193798 total:387
 ## [CloseSession] max:2 min:0 average:0.10752688172043011 total:651
 ## [InvitationAnswer] max:2 min:0 average:0.19414893617021275 total:376
 ## [SendMessageToFriend] max:2 min:0 average:0.2118343195266272 total:3380
 ## 

После чего ясно, какие именно участки кода нужно оптимизировать по производительности :)

И не забывайте, что преждевременная оптимизация -- зло.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
question for bots )
Image CAPTCHA
Enter the characters shown in the image.