04-12-2010, 09:26 PM
Lua vs Unreal Script:
Introduzione:
UnrealScript è un linguaggio di programmazione progettato per mappare naturalmente sulla necessità di programmazione del gioco entro [Epic Games]'Unreal Engine.
UnrealScript è bytecode based: il codice viene compilato in una serie di bytecode simile al P-code o il bytecode Java. In questo modo UnrealScript resta indipendente dalla piattaforma e facilita il porting verso altre piattaforme come Mac o console. UnrealScript è anche un Garbage Collection. Tutti gli oggetti e gli attori in Unreal sono garbage collection con un seguito di garbage collector-albero simile a quella della VM di Java.
Il ragionamento per indagare la performance relativa di UnrealScript vs Lua è vedere se Lua può essere utilizzato in un motore di gioco nello stesso modo che UnrealScript è così stato utilizzato con successo in tutta Unreal Engine basato giochi.
Caratteristiche:
Lua e UnrealScript sono piuttosto diverse lingue. Sono entrambi compilati in bytecode, eseguiti tramite una macchina virtuale, offrono un ambiente pointerless con garbage collection automatica, e fornire una sandbox sicura esecuzione. Questo è dove le loro somiglianze finiscono qui.
UnrealScript è un linguaggio fortemente tipizzato come Ada e C + +. Questo offre il vantaggio di catturare gli errori di tipo non intenzionale in fase di compilazione, mentre sacrificare una certa flessibilità. Lua D'altra parte è dinamicamente tipizzati. In pratica, ciò può portare a qualche tempo sprecato il debug, in alcuni casi, ma non è un problema così grande come sembra prima. Sempre a mio parere Lua potrebbe usare una garza come passare prima della compilazione.
UnrealScript supporta anche concetti importanti come il tempo, lo stato, proprietà e messa in rete attraverso la funzionalità del linguaggio esplicito. Questo rimuove un sacco di complessità che sarebbe necessaria se realizzati a livello di script. Naturalmente Lua non ha queste caratteristiche, come è inteso per uso generale, ma è il supporto per i meta-meccanismi potrebbero essere utilizzati per fornire funzionalità simili.
Performance:
Sulla base delle performance ravvicinamento citato popolarmente, Lua è 10 volte più lento di codice C. Epic sostiene che UnrealScript è una performance 20x colpo di codice C + +. Qui di seguito ho portato parametri di riferimento diversi da [The Great Win32 Computer Language Shootout] a UnrealScript nel tentativo di fare un confronto diretto delle prestazioni.
Per fare tutti i tempi ho usato scritto una piccola funzione di test in cui Lua volte il codice testato con os.clock più volte () in un ciclo. E poi getta fuori il risultato più veloce e più lento e media i tempi per ottenere una sincronizzazione finale. UnrealScript è più complessa in quanto nessuna delle funzioni documentate per il codice relazione di temporizzazione risultati coerenti. Così ho invece li lancio via UCC e un [commandlet]. Per rimuovere il sovraccarico di lancio UCC ho tempo irreale di una funzione di vuoto che poi ho subract dai test.
La release 5.0.2 Lua è usato (l'ultima versione stabile), UnrealScript era in esecuzione all'interno di Unreal Tournament 2004 build 3.323, e il C + + test è stato fatto in Microsoft Visual C + +. NET 2003.
Tutti i test eseguiti su un P4 a 2,8 GHz Intel con 1GB di memoria.
Array di accesso:
Il parametro di riferimento per Lua5 accesso array nella sparatoria ha un bug (un superfloues "+ 1" in linea 10). Ho corretto per il test di seguito.
C + +
Resultati:
n = 1000, 0.0306s
n = 3000, 0.03188s
n = 5000, 0.03564s
n = 7000, 0.03876s
UnrealScript:
Risultati:
n = 1000, 0.27252s
n = 3000, 0.81316s
n = 5000, <runaway loop error>
n = 7000, <runaway loop error>
UnrealScript ha la protezione contro passanti in fuga che viene attivato con la prova a oltre 3000. Quindi questo è tutto ciò che arriva a proseguire per questa prova.
Lua:
Risultati:
n = 1000, 0.21872s
n = 3000, 0.65432s
n = 5000, 1.09124s
n = 7000, 1.52688s
Lua sta eseguendo a circa 1/7th la velocità di C + + per n = 1000 e 1/40th per n = 7000. Si tratta di circa il 24% più veloce rispetto UnrealScript
Lua vs Python:
La prossima versione di Javascript che apparentemente non hanno una funzione molto simile a generatori di Python; l'alternativa di stile coroutine Lua è stata respinta dopo un lungo dibattito che si riassume in [Mix blog di Neil].
Come i generatori Python differiscono da coroutine Lua? La caratteristica più importante è che in Lua, coroutine.yield () è una funzione ordinaria, che può essere richiamato in qualsiasi punto la misura dinamica di una coroutine.resume () con la limitazione che non si può produrre attraverso una C richiamata (a meno che non si utilizza MikePall 's [Coco] raccolta.) In Python, resa è sintattica, e non può che essere nel corpo lessicale della funzione di generatore.
Ciò significa che i generatori Python deve essere scritto come generatori, e non può essere facilmente scomposto in parti più piccole funzioni, né possono facilmente essere ricorsive. È possibile ottenere la ricorsione da una forma di concatenamento; un messaggio sulla [mailing list Python] descrive sia il meccanismo:
!!Python
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
In Lua, si potrebbe scrivere un altro agnostico inorder funzionare come una funzione di ordine superiore:
La funzione Lua potrebbe poi essere usato sia come l'iteratore in una per ciclo:
o come una sorta di foreach funzione:
Nel tentativo di ridurre il confronto di generatori ricorsivi al minimo, ho scritto un paio di semplici programmi che generano l'infinito [funzione Ruler]. (Un interessante pagina di informazioni su questa funzione è Michael Naylor [Abacaba-Dabacaba] che comprende una esplorazione musicale.)
La funzione righello può essere generato in modo non ricorsivo, ma in questo esempio è in piedi per qualcosa come una prima ricerca in profondità, per cui ci limiteremo a esaminare l'implementazione ricorsiva. I programmi di generare i primi 2 ^ k valori nella sequenza e aggiungerli su come una sorta di test di validità, poiché è facile dimostrare che la somma dei primi 2 ^ k elementi della funzione righello è 2 ^ (k +1) -1. Python funzioni built-in e libreria standard sono a portata di mano qui, in Lua, ho dovuto attuare la somma e islice (prima k elementi di una sequenza) funziona me stesso, ma per fortuna non è difficile.
Quindi, ecco l'applicazione Lua:
e l'implementazione di Python molto simili e un po 'più breve:
La formulazione un po 'strano della ricorsione è il risultato di modificare manualmente le tailcall in una di loop, perché Python non fa tailcalls, e l'attuazione tailcall originale messo in Python anche più di uno svantaggio.
Dal momento che entrambi i programmi superato il controllo, io solo incollare i tempi comparativa qui (in secondi come riportato sopra). Io non credo che questo sia semplicemente un "Lua è più veloce di Python" benchmark "; Penso che dimostra che coroutine sono intrinsecamente più veloci, la differenza principale non si trova a dover passare i valori attraverso una catena di rendimenti.
N Lua Python
-- ----- ------
12: 0.000 0.008
13: 0.000 0.023
14: 0.008 0.055
15: 0.016 0.109
16: 0.031 0.227
17: 0.078 0.469
18: 0.148 0.961
19: 0.305 1.961
20: 0.602 4.000
21: 1.211 8.148
22: 2.430 17.211
23: 4.820 40.094
24: 9.875 94.992
Fonte: lua-users.org
Introduzione:
UnrealScript è un linguaggio di programmazione progettato per mappare naturalmente sulla necessità di programmazione del gioco entro [Epic Games]'Unreal Engine.
UnrealScript è bytecode based: il codice viene compilato in una serie di bytecode simile al P-code o il bytecode Java. In questo modo UnrealScript resta indipendente dalla piattaforma e facilita il porting verso altre piattaforme come Mac o console. UnrealScript è anche un Garbage Collection. Tutti gli oggetti e gli attori in Unreal sono garbage collection con un seguito di garbage collector-albero simile a quella della VM di Java.
Il ragionamento per indagare la performance relativa di UnrealScript vs Lua è vedere se Lua può essere utilizzato in un motore di gioco nello stesso modo che UnrealScript è così stato utilizzato con successo in tutta Unreal Engine basato giochi.
Caratteristiche:
Lua e UnrealScript sono piuttosto diverse lingue. Sono entrambi compilati in bytecode, eseguiti tramite una macchina virtuale, offrono un ambiente pointerless con garbage collection automatica, e fornire una sandbox sicura esecuzione. Questo è dove le loro somiglianze finiscono qui.
UnrealScript è un linguaggio fortemente tipizzato come Ada e C + +. Questo offre il vantaggio di catturare gli errori di tipo non intenzionale in fase di compilazione, mentre sacrificare una certa flessibilità. Lua D'altra parte è dinamicamente tipizzati. In pratica, ciò può portare a qualche tempo sprecato il debug, in alcuni casi, ma non è un problema così grande come sembra prima. Sempre a mio parere Lua potrebbe usare una garza come passare prima della compilazione.
UnrealScript supporta anche concetti importanti come il tempo, lo stato, proprietà e messa in rete attraverso la funzionalità del linguaggio esplicito. Questo rimuove un sacco di complessità che sarebbe necessaria se realizzati a livello di script. Naturalmente Lua non ha queste caratteristiche, come è inteso per uso generale, ma è il supporto per i meta-meccanismi potrebbero essere utilizzati per fornire funzionalità simili.
Performance:
Sulla base delle performance ravvicinamento citato popolarmente, Lua è 10 volte più lento di codice C. Epic sostiene che UnrealScript è una performance 20x colpo di codice C + +. Qui di seguito ho portato parametri di riferimento diversi da [The Great Win32 Computer Language Shootout] a UnrealScript nel tentativo di fare un confronto diretto delle prestazioni.
Per fare tutti i tempi ho usato scritto una piccola funzione di test in cui Lua volte il codice testato con os.clock più volte () in un ciclo. E poi getta fuori il risultato più veloce e più lento e media i tempi per ottenere una sincronizzazione finale. UnrealScript è più complessa in quanto nessuna delle funzioni documentate per il codice relazione di temporizzazione risultati coerenti. Così ho invece li lancio via UCC e un [commandlet]. Per rimuovere il sovraccarico di lancio UCC ho tempo irreale di una funzione di vuoto che poi ho subract dai test.
La release 5.0.2 Lua è usato (l'ultima versione stabile), UnrealScript era in esecuzione all'interno di Unreal Tournament 2004 build 3.323, e il C + + test è stato fatto in Microsoft Visual C + +. NET 2003.
Tutti i test eseguiti su un P4 a 2,8 GHz Intel con 1GB di memoria.
Array di accesso:
Il parametro di riferimento per Lua5 accesso array nella sparatoria ha un bug (un superfloues "+ 1" in linea 10). Ho corretto per il test di seguito.
C + +
Codice PHP:
// -*- mode: c++ -*-
// $Id: ary3.g++,v 1.2 2001/06/20 03:20:02 doug Exp $ // http://www.bagley.org/~doug/shootout/
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
int i, k, n = ((argc == 2) ? atoi(argv[1]) : 1);
typedef vector<int> ARY;
ARY x(n);
ARY y(n);
for (i=0; i<n; i++) {
x[i] = i + 1;
}
for (k=0; k<1000; k++) {
for (int i = n - 1; i >= 0; --i) {
y[i] += x[i];
}
}
cout << y[0] << " " << y.back() << endl; }
Resultati:
n = 1000, 0.0306s
n = 3000, 0.03188s
n = 5000, 0.03564s
n = 7000, 0.03876s
UnrealScript:
Codice PHP:
static final function string ArrayTest( optional int n ) {
local int i, k;
local array<int> x;
local array<int> y;
if ( n == 0 ) {
n = 1;
}
x.Length = n;
y.Length = n;
for ( i = 0; i < n; i++ ) {
x[i] = i + 1;
}
for ( k=0; k<1000; k++ ) {
for (i = n-1; i >= 0; i--) {
y[i] += x[i];
}
}
return ( y[0]$ " " $y[n-1] );
}
Risultati:
n = 1000, 0.27252s
n = 3000, 0.81316s
n = 5000, <runaway loop error>
n = 7000, <runaway loop error>
UnrealScript ha la protezione contro passanti in fuga che viene attivato con la prova a oltre 3000. Quindi questo è tutto ciò che arriva a proseguire per questa prova.
Lua:
Codice PHP:
function array_test( n )
local x, y = {}, {}
for i=1,n do
x[i] = i
y[i] = 0
end
for k=1,1000 do
for j=n,1,-1 do
y[j] = y[j] + x[j]
end
end
return y[1] .. " " .. y[n]
end
Risultati:
n = 1000, 0.21872s
n = 3000, 0.65432s
n = 5000, 1.09124s
n = 7000, 1.52688s
Lua sta eseguendo a circa 1/7th la velocità di C + + per n = 1000 e 1/40th per n = 7000. Si tratta di circa il 24% più veloce rispetto UnrealScript
Lua vs Python:
La prossima versione di Javascript che apparentemente non hanno una funzione molto simile a generatori di Python; l'alternativa di stile coroutine Lua è stata respinta dopo un lungo dibattito che si riassume in [Mix blog di Neil].
Come i generatori Python differiscono da coroutine Lua? La caratteristica più importante è che in Lua, coroutine.yield () è una funzione ordinaria, che può essere richiamato in qualsiasi punto la misura dinamica di una coroutine.resume () con la limitazione che non si può produrre attraverso una C richiamata (a meno che non si utilizza MikePall 's [Coco] raccolta.) In Python, resa è sintattica, e non può che essere nel corpo lessicale della funzione di generatore.
Ciò significa che i generatori Python deve essere scritto come generatori, e non può essere facilmente scomposto in parti più piccole funzioni, né possono facilmente essere ricorsive. È possibile ottenere la ricorsione da una forma di concatenamento; un messaggio sulla [mailing list Python] descrive sia il meccanismo:
!!Python
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
In Lua, si potrebbe scrivere un altro agnostico inorder funzionare come una funzione di ordine superiore:
Codice PHP:
function inorder(f, t)
if t then
inorder(f, t.left)
f(t.label)
return inorder(f, t.right)
end
end
La funzione Lua potrebbe poi essere usato sia come l'iteratore in una per ciclo:
Codice PHP:
for label in coroutine.wrap(inorder), coroutine.yield, t do
-- something with label
end
o come una sorta di foreach funzione:
Codice PHP:
inorder(print, t)
Nel tentativo di ridurre il confronto di generatori ricorsivi al minimo, ho scritto un paio di semplici programmi che generano l'infinito [funzione Ruler]. (Un interessante pagina di informazioni su questa funzione è Michael Naylor [Abacaba-Dabacaba] che comprende una esplorazione musicale.)
La funzione righello può essere generato in modo non ricorsivo, ma in questo esempio è in piedi per qualcosa come una prima ricerca in profondità, per cui ci limiteremo a esaminare l'implementazione ricorsiva. I programmi di generare i primi 2 ^ k valori nella sequenza e aggiungerli su come una sorta di test di validità, poiché è facile dimostrare che la somma dei primi 2 ^ k elementi della funzione righello è 2 ^ (k +1) -1. Python funzioni built-in e libreria standard sono a portata di mano qui, in Lua, ho dovuto attuare la somma e islice (prima k elementi di una sequenza) funziona me stesso, ma per fortuna non è difficile.
Quindi, ecco l'applicazione Lua:
Codice PHP:
function ruler(put, k)
for i = 1, k do
put(i)
ruler(put, i-1)
end
end
function eachruler()
return coroutine.wrap(function()
return ruler(coroutine.yield, 100)
end)
end
function sumseq(k, f, o, s)
local sum = 0
for v in f, o, s do
k, sum = k-1, sum + v
if k <= 0 then break end
end
return sum
end
local howmany = tonumber(arg[1]) or 24
local now = os.clock()
local sum = sumseq(2^howmany, eachruler())
local took = os.clock()-now
print(("%2i: %7.3f seconds %i check %i"):format(howmany, took, sum, 2^(howmany+1)-1))
e l'implementazione di Python molto simili e un po 'più breve:
Codice PHP:
!Python
from itertools import islice
from sys import argv
from time import clock
def ruler(k):
for i in range(1, k+1):
yield i
for x in ruler(i-1): yield x
howmany = int(argv[1])
now = clock()
total = sum(islice(ruler(100), 2**howmany))
took = clock()-now
print "%2d: %7.3f seconds %d check %d" % (howmany, took, total, 2**(howmany+1)-1)
La formulazione un po 'strano della ricorsione è il risultato di modificare manualmente le tailcall in una di loop, perché Python non fa tailcalls, e l'attuazione tailcall originale messo in Python anche più di uno svantaggio.
Dal momento che entrambi i programmi superato il controllo, io solo incollare i tempi comparativa qui (in secondi come riportato sopra). Io non credo che questo sia semplicemente un "Lua è più veloce di Python" benchmark "; Penso che dimostra che coroutine sono intrinsecamente più veloci, la differenza principale non si trova a dover passare i valori attraverso una catena di rendimenti.
N Lua Python
-- ----- ------
12: 0.000 0.008
13: 0.000 0.023
14: 0.008 0.055
15: 0.016 0.109
16: 0.031 0.227
17: 0.078 0.469
18: 0.148 0.961
19: 0.305 1.961
20: 0.602 4.000
21: 1.211 8.148
22: 2.430 17.211
23: 4.820 40.094
24: 9.875 94.992
Fonte: lua-users.org