ObjectScript — новый встраиваемый и очень легкий объектно-ориентированный язык программирования с открытым исходным кодом. ObjectScript расширяет возможности таких языков, как JavaScript, Lua и PHP. Синтаксис в основном взят из JavaScript, множественное присваивание — из Lua, работа со свойствами — из PHP.
ObjectScript 0.97-vm2 быстрее, чем PHP 5.3.3 и JS на 34% и 61% соответственно.
Как тестировалось
Для тестирования был взят алгоритм Fannkuch. Довольно удобный тест, одна функция с параметром, при увеличении параметра на 1, количество вычислений увеличивается примерно в 10 раз. Соответственно, чем меньше было затрачено времени на выполнение теста, тем лучше.
Fannkuch был реализован на ObjectScript, полный исходник:
print arg
var fannkuch = function(n)
{
var p, q, s, sign, maxflips, sum = [], [], [], 1, 0, 0
var i
for(i=1; i<=n; i++) p[i], q[i], s[i] = i, i, i
for(;;){
// Copy and flip.
var q1 = p[1] // Cache 1st element.
if(q1 != 1){
for(i=2; i<=n; i++) q[i] = p[i] // Work on a copy.
var flips = 1
for(;;){
var qq = q[q1]
if(qq == 1){ // ... until 1st element is 1.
sum = sum + sign*flips
if(flips > maxflips){
maxflips = flips
} // New maximum?
break
}
q[q1] = q1
if(q1 >= 4){
var i, j = 2, q1 - 1
for(;;){ q[i], q[j] = q[j], q[i]; if(++i >= --j) break }
}
q1 = qq; flips++
}
}
// Permute.
if(sign == 1){
p[2], p[1] = p[1], p[2] sign = -1 // Rotate 1<-2.
}else{
p[2], p[3] = p[3], p[2] sign = 1 // Rotate 1<-2 and 1<-2<-3.
for(i = 3;; i++){
// print "mark 4"
var sx = s[i]
if(sx != 1){ s[i] = sx-1 break }
if(i == n) return sum, maxflips; // Out of permutations.
s[i] = i
// Rotate 1<-...<-i+1.
var t = p[1] for(var j = 1; j <= i; j++){ p[j] = p[j+1] } p[i+1] = t
}
}
}
}
var n = numberof(arg && arg[1]) || 5
var start_time = getTimeSec()
var sum, flips = fannkuch(n)
echo(
sum"n"
"Pfannkuchen("n") = "flips"n"
"time = ", (getTimeSec() - start_time)"n"
)
На PHP, полный исходник:
<?php
function fannkuch($n)
{
$p = array();
$q = array();
$s = array();
$sign = 1;
$maxflips = $sum = 0;
for($i=1; $i<=$n; $i++) $p[$i] = $q[$i] = $s[$i] = $i;
for(;;){
// Copy and flip.
$q1 = $p[1]; // Cache 1st element.
if($q1 != 1){
for($i=2; $i<=$n; $i++) $q[$i] = $p[$i]; // Work on a copy.
$flips = 1;
for(;;){
$qq = $q[$q1];
if($qq == 1){ // ... until 1st element is 1.
$sum += $sign*$flips;
if($flips > $maxflips){
$maxflips = $flips;
} // New maximum?
break;
}
$q[$q1] = $q1;
if($q1 >= 4){
$i = 2; $j = $q1 - 1;
for(;;){ $tmp = $q[$i]; $q[$i] = $q[$j]; $q[$j] = $tmp; if(++$i >= --$j) break; }
}
$q1 = $qq; $flips++;
}
}
// Permute.
if($sign == 1){
$tmp = $p[2]; $p[2] = $p[1]; $p[1] = $tmp; $sign = -1; // Rotate 1<-2.
}else{
$tmp = $p[2]; $p[2] = $p[3]; $p[3] = $tmp; $sign = 1; // Rotate 1<-2 and 1<-2<-3.
for($i = 3;; $i++){
$sx = $s[$i];
if($sx != 1){ $s[$i] = $sx-1; break; }
if($i == $n) return array($sum, $maxflips); // Out of permutations.
$s[$i] = $i;
// Rotate 1<-...<-i+1.
$t = $p[1]; for($j = 1; $j <= $i; $j++){ $p[$j] = $p[$j+1]; } $p[$i+1] = $t;
}
}
}
}
function getTimeSec(){
list($usec, $sec) = explode(" ",microtime());
return ($usec + $sec);
}
$n = isset($argv[1]) ? $argv[1] : 5;
echo "n: $nn";
$start_time = getTimeSec();
$r = fannkuch($n);
$sum = $r[0]; $flips = $r[1];
echo("$sumnPfannkuchen($n) = $flipsn"
. "time = ".(getTimeSec() - $start_time)."n");
На JavaScript, полный исходник:
var fannkuch = function(n)
{
var p = [], q = [], s = [], sign = 1, maxflips = 0, sum = 0;
var i;
for(i=1; i<=n; i++) p[i] = q[i] = s[i] = i;
for(;;){
// Copy and flip.
var q1 = p[1]; // Cache 1st element.
if(q1 != 1){
for(i=2; i<=n; i++) q[i] = p[i]; // Work on a copy.
var flips = 1;
for(;;){
var qq = q[q1];
if(qq == 1){ // ... until 1st element is 1.
sum = sum + sign*flips;
if(flips > maxflips){
maxflips = flips;
} // New maximum?
break;
}
q[q1] = q1;
if(q1 >= 4){
var i = 2, j = q1 - 1
for(;;){ var tmp = q[i]; q[i] = q[j]; q[j] = tmp; if(++i >= --j) break; }
}
q1 = qq; flips++;
}
}
// Permute.
if(sign == 1){
var tmp = p[2]; p[2] = p[1]; p[1] = tmp; sign = -1; // Rotate 1<-2.
}else{
var tmp = p[2]; p[2] = p[3]; p[3] = tmp; sign = 1; // Rotate 1<-2 and 1<-2<-3.
for(i = 3;; i++){
// print "mark 4"
var sx = s[i];
if(sx != 1){ s[i] = sx-1; break; }
if(i == n) return [sum, maxflips]; // Out of permutations.
s[i] = i;
// Rotate 1<-...<-i+1.
var t = p[1]; for(var j = 1; j <= i; j++){ p[j] = p[j+1]; } p[i+1] = t;
}
}
}
}
function getTimeSec(){
var d = new Date();
return (d.getTime() + d.getMilliseconds() / 1000.0) / 1000.0;
}
var n = 10;
var start_time = getTimeSec();
var r = fannkuch(n);
var sum = r[0], flips = r[1];
WScript.Echo(
sum,"n",
"Pfannkuchen(",n,") = ",flips,"n",
"time = ",(getTimeSec() - start_time),"n"
)
Тестирование проводилось на платформе: Windows 7, CPU Core i7 2630QM 2Ghz. Fannkuch запускался с параметром 10.
ObjectScript 0.97-vm2 релизная сборка с числовым типом double (с float получается быстрее примерно на 10%, но эти цифры я в статье не привожу, т.к. PHP и JS имеют числовой тип double, PHP также имеет целочисленный тип):
c:SourcesOSbinos.exe test_fannkuch.os 10
вывод (время указано среднее за 10 итераций):
73196
Pfannkuchen(10) = 38
time = 20.0991
PHP 5.3.3:
c:WebServersusrbinphp5.exe test_fannkuch.php 10
вывод (время указано среднее за 10 итераций):
73196
Pfannkuchen(10) = 38
time = 26.853
JS (параметр 10 находится внутри test_fannkuch.js):
Cscript.exe test_fannkuch.js
вывод (время указано среднее за 10 итераций):
73196
Pfannkuchen( 10 ) = 38
time = 32.3313
Сводные данные
Чем меньше время, тем лучше.
ObjectScript — 20.099 сек
PHP — 26.853 сек
JS — 32.331 сек
Возьмем за эталон время 20.099 и сведем результаты в процентные соотношения:
- OS быстрее PHP на 34%
- OS быстрее JS на 61%
Вы можете скачать исходники ObjectScript и пример из данной статьи по этой ссылке, открыть proj.win32examples.sln, проект profile_benchmark.
Характеристики языка ObjectScript
ООП — есть
Функции как значения первого класса — есть
Замыкания — есть
Сборщик мусора — Tri-Color Incremental Garbage collection
Компиляция в байткод — есть
Загрузка откомпилированной программы — есть
Модульность — есть
Подгружаемые в рантайме модули — есть
Кроссплатформенность — есть
Интеграция с C/C++ — есть
Идеи для языка позаимствованы из JavaScript, Lua и PHP
Цели и задачи языка: скриптование игровой и программной логики, кросс переносимость, веб и серверная разработка
автор — Евгений Головин (разработчик oxsar.ru и др.)
срок разработки ObjectScript — 2 месяца
Развитие и продвижение ObjectScript
Потенциал дальнейшей оптимизации по скорости еще не исчерпан, но текущие характеристики выглядят довольно не плохо. Видимо с дальнейшей оптимизацией можно немного притормозить. Планирую занятся изучением биндингов к разным языкам и сделать таки реально удобный биндинга C++ к OS.
С большим удовольствием устроюсь к вам на работу и заверну нужный вам API в OS :)
P.S. проекту требуются инвестиции, по вопросам сотрудничества и просто вопросам можно смело писать на evgeniy.golovin[AT]unitpoint.ru
Другие релевантные статьи об ObjectScript:
- ObjectScript API, интеграция с C++. Часть 3: подключение модуля с функциями на C++
- ObjectScript API, интеграция с C++. Часть 2: выполнение скрипта на OS из C++
- ObjectScript API, интеграция с C++. Часть 1: работа со стеком, вызов функций OS из C++
- ObjectScript — новый язык программирования
Автор: evgeniyup