I created a benchmark in C++ for testing and comparing TeaScript and its competitor ChaiScript by computing the Fibonacci number of 25 recursively. As a reference I did the same also in C++. The complete source code of the benchmark is available below.
The result is pretty amazing, since with the used pre-release 0.8.0 of TeaScript I did not profile and optimize yet. This is a task for a future release. The latest release of TeaScript is available in the download section.
(UPDATE 2023-01-17): I created a Github Repository for this and all future benchmarks comparing script languages in and for C++.
(UPDATE 2024-03-08): I created a new benchmark for filling a 32 bit Full HD (or UHD) image buffer pixel by pixel. Read the results here: New Benchmark.
Here is the benchmark result: Computing time of fibonacci( 25 ) measured in seconds. Shorter is better/faster, longer is slower.
Diagram of benchmark result computing Fibonacci.
Some technical information about the environment: 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.
Some notes to Python and Lua: Python as well as Lua are actually not in competition with TeaScript from the performance point of view since TeaScript and ChaiScript are real script languages (and header only C++ Libraries), but Python and Lua are compiling the source to a bytecode and executing it in a virtual stack machine (Python) or in an even a more complex virtual machine (Lua).
This may change with a later version of TeaScript.
Here is the C++ source code of the benchmark:
/*
* SPDX-FileCopyrightText: Copyright (C) 2023 Florian Thake, <contact |the-at-symbol| tea-age.solutions>.
* SPDX-License-Identifier: MIT
*/
#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;
}
... and this is the screenshot from the run:
Screenshot of the benchmark run.
BTW: The download package of TeaScript contains a script (beside others) for calculating Fibonacci Numbers inclusive time measurement.