Angelscript/docs/manual/doc_finetuning.html

201 lines
17 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Fine tuning</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">AngelScript
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('doc_finetuning.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">Fine tuning </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Here's a few recommendations to get the most performance out of AngelScript.</p>
<h1><a class="anchor" id="doc_finetuning_1"></a>
Cache the functions and types</h1>
<p>Doing searches by function declaration or name is rather time consuming and should not be done more than once per function that will be called. The same goes for the types that you might use it.</p>
<p>Also try to use the actual <a class="el" href="classas_i_script_function.html">asIScriptFunction</a> or <a class="el" href="classas_i_type_info.html">asITypeInfo</a> pointers instead of the ids where possible. This will save the engine from translating the <br />
id to the actual object.</p>
<p>You may use the user data in the various engine interfaces to store the cached information. For example, store a structure with the commonly used class methods as <a class="el" href="classas_i_type_info.html#a5e8ea071f1c1f3b7c6dfc1950bec73f4">user data</a> in the <a class="el" href="classas_i_type_info.html">asITypeInfo</a> interface. This way you will have quick access to the functions when they need to be called.</p>
<h1><a class="anchor" id="doc_finetuning_2"></a>
Reuse the context object</h1>
<p>The context object is a heavy weight object and you should avoid allocating new instances for each call. The object has been designed to be reused for multiple calls.</p>
<h2><a class="anchor" id="doc_finetuning_2_1"></a>
Context pool</h2>
<p>Ideally the application will keep a simple memory pool of allocated context objects, where new objects are only allocated if the is no free objects in the pool.</p>
<p>By using the engine's <a class="el" href="classas_i_script_engine.html#ae5ba9fe99b72c60392cdaeef164f2c65">context callbacks</a>, this context pool will also be automatically available to the engine for use in internal calls and the add-ons.</p>
<p>The code that wants to use a context from the pool should use the <a class="el" href="classas_i_script_engine.html#a32391ee83e58083b406ba068ab2ee049">RequestContext</a> and <a class="el" href="classas_i_script_engine.html#a22e42bf32902cbd6885731a6beeaca20">ReturnContext</a> methods instead of the <a class="el" href="classas_i_script_engine.html#a2630e1cd03ffab0fee9b820bf0afe42a">CreateContext</a> method.</p>
<p>Here's a simple implementation of a context pool.</p>
<div class="fragment"><div class="line">std::vector&lt;asIScriptContext *&gt; pool;</div>
<div class="line"><a class="code" href="classas_i_script_context.html">asIScriptContext</a> *RequestContextCallback(<a class="code" href="classas_i_script_engine.html">asIScriptEngine</a> *engine, <span class="keywordtype">void</span> *param)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Get a context from the pool, or create a new</span></div>
<div class="line"> <a class="code" href="classas_i_script_context.html">asIScriptContext</a> *ctx = 0;</div>
<div class="line"> <span class="keywordflow">if</span>( pool.size() )</div>
<div class="line"> {</div>
<div class="line"> ctx = *pool.rbegin();</div>
<div class="line"> pool.pop_back();</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">else</span></div>
<div class="line"> ctx = engine-&gt;<a class="code" href="classas_i_script_engine.html#a2630e1cd03ffab0fee9b820bf0afe42a">CreateContext</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> ctx;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> ReturnContextToPool(<a class="code" href="classas_i_script_engine.html">asIScriptEngine</a> *engine, <a class="code" href="classas_i_script_context.html">asIScriptContext</a> *ctx, <span class="keywordtype">void</span> *param)</div>
<div class="line">{</div>
<div class="line"> pool.push_back(ctx);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Unprepare the context to free non-reusable resources</span></div>
<div class="line"> ctx-&gt;<a class="code" href="classas_i_script_context.html#ae3c18a2cc66c56f840e6ee4310287f65">Unprepare</a>();</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="doc_finetuning_2_2"></a>
Nested calls</h2>
<p>Another form of reusing a context is to use nested calls.</p>
<p>Whenever an application registered function that is called from a script needs to execute another script it can reuse the already active context for a nested call. This way it is not necessary to look for an available context from a pool or allocate a new context just for this call.</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> Func()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// Get the active context</span></div>
<div class="line"> <a class="code" href="classas_i_script_context.html">asIScriptContext</a> *ctx = <a class="code" href="group__api__principal__functions.html#gad3a20dc58093b92a5a44c7b6ada34a10">asGetActiveContext</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Store the current context state so we can restore it later</span></div>
<div class="line"> <span class="keywordflow">if</span>( ctx &amp;&amp; ctx-&gt;<a class="code" href="classas_i_script_context.html#ad8f7637a23d67e227d07f65621b6cdd6">PushState</a>() &gt; 0 )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Use the context normally, e.g.</span></div>
<div class="line"> <span class="comment">// ctx-&gt;Prepare(...);</span></div>
<div class="line"> <span class="comment">// ctx-&gt;Execute(...);</span></div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Once done, restore the previous state</span></div>
<div class="line"> ctx-&gt;<a class="code" href="classas_i_script_context.html#a5d963974625e582799b5d911d182d9be">PopState</a>();</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="doc_finetuning_3"></a>
Compile scripts without line cues</h1>
<p>The line cues are normally placed in the bytecode between each script statement. These are where the VM will allow the execution to be suspended, and also where the line callback is invoked.</p>
<p>If you do not need to receive a callback for every statement executed in a script then you may get a little more performance out of the script by compiling without the line cues.</p>
<p>The line callback will still work and is guaranteed to be invoked at least once per loop and every function call in the script to allow the application to interrupt infinite loops or infinitely recursive calls.</p>
<div class="fragment"><div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a1bce4e5f573a2ca0ff55163e28f761dd">SetEngineProperty</a>(<a class="code" href="angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0fa73b396e4ea6376f0962d19add962bd91">asEP_BUILD_WITHOUT_LINE_CUES</a>, <span class="keyword">true</span>);</div>
</div><!-- fragment --><h1><a class="anchor" id="doc_finetuning_4"></a>
Disable thread safety</h1>
<p>If your application only uses one thread to invoke the script engine, then it may be worth it to compile the library without the thread safety to gain a little more performance.</p>
<p>To do this, define the AS_NO_THREADS flag in the as_config.h header or in the project settings when compiling the library.</p>
<h1><a class="anchor" id="doc_finetuning_5"></a>
Turn off automatic garbage collection</h1>
<p>While garbage collection is important in long running applications, it may be of interest to turn off the automatic garbage collection and then run the garbage collector manually in a controlled manner. The garbage collector is incremental so you shouldn't see long stalls while it is running, but it will consume CPU cycles that may be needed for other things.</p>
<p>To turn off the automatic garbage collector set the engine property <a class="el" href="angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0fa9b5d1d8ff5143a6a77dfd18143d87c7d">asEP_AUTO_GARBAGE_COLLECT</a> to false.</p>
<div class="fragment"><div class="line">engine-&gt;<a class="code" href="classas_i_script_engine.html#a1bce4e5f573a2ca0ff55163e28f761dd">SetEngineProperty</a>(<a class="code" href="angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0fa9b5d1d8ff5143a6a77dfd18143d87c7d">asEP_AUTO_GARBAGE_COLLECT</a>, <span class="keyword">false</span>);</div>
</div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_gc.html">Garbage collection</a></dd></dl>
<h1><a class="anchor" id="doc_finetuning_6"></a>
Compare native calling convention versus generic calling convention</h1>
<p>If you have specific functions that are called very frequently it may be worth comparing the performance between binding the functions using native calling convention versus the generic calling convention. It is not possible to generalize and say that one is always faster than the other, as it will vary depending on the function signature and the platforms ABI complexity.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_generic.html">The generic calling convention</a>, <a class="el" href="doc_register_func.html#doc_register_func_2">Calling convention</a> </dd></dl>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<div class="ttc" id="aclassas_i_script_context_html_a5d963974625e582799b5d911d182d9be"><div class="ttname"><a href="classas_i_script_context.html#a5d963974625e582799b5d911d182d9be">asIScriptContext::PopState</a></div><div class="ttdeci">virtual int PopState()=0</div><div class="ttdoc">Restores the state to resume previous script execution.</div></div>
<div class="ttc" id="aclassas_i_script_context_html"><div class="ttname"><a href="classas_i_script_context.html">asIScriptContext</a></div><div class="ttdoc">The interface to the virtual machine.</div><div class="ttdef"><b>Definition:</b> angelscript.h:2717</div></div>
<div class="ttc" id="aangelscript_8h_html_a53c2e8a74ade77c928316396394ebe0fa9b5d1d8ff5143a6a77dfd18143d87c7d"><div class="ttname"><a href="angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0fa9b5d1d8ff5143a6a77dfd18143d87c7d">asEP_AUTO_GARBAGE_COLLECT</a></div><div class="ttdeci">@ asEP_AUTO_GARBAGE_COLLECT</div><div class="ttdoc">Enable or disable automatic garbage collection. Default: true.</div><div class="ttdef"><b>Definition:</b> angelscript.h:186</div></div>
<div class="ttc" id="aclassas_i_script_engine_html"><div class="ttname"><a href="classas_i_script_engine.html">asIScriptEngine</a></div><div class="ttdoc">The engine interface.</div><div class="ttdef"><b>Definition:</b> angelscript.h:1092</div></div>
<div class="ttc" id="aclassas_i_script_context_html_ae3c18a2cc66c56f840e6ee4310287f65"><div class="ttname"><a href="classas_i_script_context.html#ae3c18a2cc66c56f840e6ee4310287f65">asIScriptContext::Unprepare</a></div><div class="ttdeci">virtual int Unprepare()=0</div><div class="ttdoc">Frees resources held by the context.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a2630e1cd03ffab0fee9b820bf0afe42a"><div class="ttname"><a href="classas_i_script_engine.html#a2630e1cd03ffab0fee9b820bf0afe42a">asIScriptEngine::CreateContext</a></div><div class="ttdeci">virtual asIScriptContext * CreateContext()=0</div><div class="ttdoc">Creates a new script context.</div></div>
<div class="ttc" id="aangelscript_8h_html_a53c2e8a74ade77c928316396394ebe0fa73b396e4ea6376f0962d19add962bd91"><div class="ttname"><a href="angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0fa73b396e4ea6376f0962d19add962bd91">asEP_BUILD_WITHOUT_LINE_CUES</a></div><div class="ttdeci">@ asEP_BUILD_WITHOUT_LINE_CUES</div><div class="ttdoc">Remove SUSPEND instructions between each statement. Default: false.</div><div class="ttdef"><b>Definition:</b> angelscript.h:170</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a1bce4e5f573a2ca0ff55163e28f761dd"><div class="ttname"><a href="classas_i_script_engine.html#a1bce4e5f573a2ca0ff55163e28f761dd">asIScriptEngine::SetEngineProperty</a></div><div class="ttdeci">virtual int SetEngineProperty(asEEngineProp property, asPWORD value)=0</div><div class="ttdoc">Dynamically change some engine properties.</div></div>
<div class="ttc" id="aclassas_i_script_context_html_ad8f7637a23d67e227d07f65621b6cdd6"><div class="ttname"><a href="classas_i_script_context.html#ad8f7637a23d67e227d07f65621b6cdd6">asIScriptContext::PushState</a></div><div class="ttdeci">virtual int PushState()=0</div><div class="ttdoc">Backups the current state to prepare the context for a nested call.</div></div>
<div class="ttc" id="agroup__api__principal__functions_html_gad3a20dc58093b92a5a44c7b6ada34a10"><div class="ttname"><a href="group__api__principal__functions.html#gad3a20dc58093b92a5a44c7b6ada34a10">asGetActiveContext</a></div><div class="ttdeci">AS_API asIScriptContext * asGetActiveContext()</div><div class="ttdoc">Returns the currently active context.</div></div>
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated on Sat Dec 5 2020 23:20:24 for AngelScript by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.18 </li>
</ul>
</div>
</body>
</html>