Начнем с оффтопика. Надо сказать, что для разработки под 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