ObjectScript — новый язык программирования, быстрее чем PHP и JS

в 2:52, , рубрики: api, javascript, Lua, ObjectScript, objectscript api, open source, php, Программирование, метки: , , , , ,

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:

Автор: evgeniyup

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js