Ich habe einen Benchmark in C++ zum Testen und Vergleichen von TeaScript und dem Wettbewerber ChaiScript im rekursiven Ausrechnen der Fibonacci Zahl 25 erstellt. Als Referenz habe ich dies auch noch in C++ gemacht. Der komplette Source Code des Benchmarks ist unten gelistet.
Das Ergebnis ist wirklich erstaunlich, da ich im Pre-Release 0.8.0 von TeaScript noch gar nicht „profiled“ und optimiert habe. Dies ist erst für ein späteres Pre-Release geplant.
(UPDATE 2023-01-17): Ich habe für diesen und allen zukünftigen Benchmarks für „Skriptsprachen in und für C++“ ein Github Repository erstellt.
Hier ist das Benchmark Ergebnis: Zeitmessung der Ausrechnung von fibonacci( 25 )
in Sekunden. Kürzer ist besser/schneller, länger ist langsamer.
Ein paar technische Infos zur Umgebung:
OS: Windows 10 21H2 (64bit)
CPU: Intel Core i7-11700
RAM: 32 GB
Compiler/Build: Visual Studio 2022 Community (17.4.3), Release/x64 (AVX2), C++20 (selben Settings wie in meinem Blog Post).
Ein paar Anmerkungen zu Python und Lua:
Python und Lua stehen derzeit aus Performanz-Sicht nicht im Wettbewerb zu TeaScript, da TeaScript als auch ChaiScript echte Skriptsprachen (und Header-Only C++ Libraries) sind, wohingegen Python und auch Lua den Source Code in einen Bytecode kompilieren und in einer virtuellen Stack-Maschine (Python) oder in einer noch komplexeren virtuellen Maschine (Lua) ausführen.
Dies mag sich in der Zukunft mit der Pro Version von TeaScript ändern.
Hier ist der C++ Quellcode des Benchmarks:
/*
* SPDX-FileCopyrightText: Copyright (C) 2023 Florian Thake, <contact |the-at-symbol| tea-age.solutions>. All rights reserved.
*/
#include <cstdlib> // EXIT_SUCCESS
#include <cstdio>
#include <iostream>
#include <chrono>
#include <teascript/Parser.hpp>
#include <teascript/CoreLibrary.hpp>
#include <chaiscript/chaiscript.hpp>
// recursive fibonacci function in TeaScript
constexpr char tea_code[] = R"_SCRIPT_(
func fib( x ) {
if( x == 1 or x == 0 ) {
x
} else {
fib( x - 1 ) + fib( x - 2 )
}
}
fib(25)
)_SCRIPT_";
// recursive fibonacci function in ChaiScript
constexpr char chai_code[] = R"_SCRIPT_(
def fib( x )
{
if( x == 0 || x == 1 ) {
return x;
} else {
return fib( x - 1 ) + fib( x - 2 );
}
}
fib(25);
)_SCRIPT_";
auto Now()
{
return std::chrono::steady_clock::now();
}
double CalcTimeInSecs( auto s, auto e )
{
std::chrono::duration<double> const timesecs = e - s;
return timesecs.count();
}
double exec_tea()
{
teascript::Context c;
teascript::CoreLibrary().Bootstrap( c );
teascript::Parser p;
auto ast = p.Parse( tea_code );
try {
auto start = Now();
auto teares = ast->Eval( c );
auto end = Now();
std::cout << "value: " << teares.GetAsLongLong() << std::endl;
return CalcTimeInSecs( start, end );
} catch( teascript::exception::runtime_error const &ex ) {
teascript::util::pretty_print( ex );
} catch( std::exception const &ex ) {
puts( ex.what() );
}
return -1.0;
}
double exec_chai()
{
chaiscript::ChaiScript chai;
auto ast = chai.parse( chai_code );
try {
auto start = Now();
auto chres = chai.eval( *ast );
auto end = Now();
std::cout << "value: " << chaiscript::boxed_cast<int>(chres) << std::endl;
return CalcTimeInSecs( start, end );
} catch( chaiscript::Boxed_Value const &bv ) {
puts( chaiscript::boxed_cast<chaiscript::exception::eval_error const &>(bv).what() );
} catch( std::exception const &ex ) {
puts( ex.what() );
}
return -1.0;
}
// recursive fibonacci function in C++
long long fib( long long x )
{
if( x == 0 || x == 1 ) {
return x;
} else {
return fib( x - 1 ) + fib( x - 2 );
}
}
double exec_cpp()
{
try {
auto start = Now();
auto res = fib( 25 );
auto end = Now();
std::cout << "value: " << res << std::endl;
return CalcTimeInSecs( start, end );
} catch( std::exception const &ex ) {
puts( ex.what() );
}
return -1.0;
}
int main()
{
std::cout << std::fixed;
std::cout << std::setprecision( 8 );
std::cout << "Benchmarking TeaScript and ChaiScript in calculating Fibonacci of 25...\n";
std::cout << "... and C++ as a reference ... \n";
std::cout << "\nStart Test C++" << std::endl;
for( int i = 3; i != 0; --i ) {
auto secs = exec_cpp();
std::cout << "Calculation took: " << secs << " seconds." << std::endl;
}
std::cout << "\nStart Test TeaScript" << std::endl;
for( int i = 3; i != 0; --i ) {
auto secs = exec_tea();
std::cout << "Calculation took: " << secs << " seconds." << std::endl;
}
std::cout << "\nStart Test ChaiScript" << std::endl;
for( int i = 3; i != 0; --i ) {
auto secs = exec_chai();
std::cout << "Calculation took: " << secs << " seconds." << std::endl;
}
puts( "\n\nTest end." );
return EXIT_SUCCESS;
}
… und hier der Screenshot des Durchlaufs:
Im Download Package von TeaScript ist übrigens auch (neben anderen Skripten) ein Skript zum Ausrechnen von Fibonacci Zahlen inklusive Zeitmessung enthalten.