<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=P34CH+34732</id>
	<title>AlliedModders Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=P34CH+34732"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/P34CH_34732"/>
	<updated>2026-05-21T01:37:56Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(AMX_Mod_X_Scripting)&amp;diff=4463</id>
		<title>Optimizing Plugins (AMX Mod X Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Optimizing_Plugins_(AMX_Mod_X_Scripting)&amp;diff=4463"/>
		<updated>2007-04-13T02:37:48Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: /* Local Strings */ Fixed BAILOPAN's nonsense code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
[[Admin-Mod]] and [[AMX Mod X]] became very popular because of their easy to use scripting language.  However, the words &amp;quot;scripting language&amp;quot; come with a lot of loaded preconceptions.  Most people assume that because it's scripted:&lt;br /&gt;
*You can't possibly make it any faster&lt;br /&gt;
*It's pre-compiled, so it's already quite fast&lt;br /&gt;
*Details don't matter, as it's only &amp;quot;scripting&amp;quot; anyway&lt;br /&gt;
&lt;br /&gt;
Especially, with [[Pawn]] (formerly Small), none of these are true.  The compiler, in fact, is very poor at optimizing, and you can '''greatly''' increase the speed and efficiency of your plugins by keeping a few rules in mind.  Remember - it's more important to minimize instructions than it is to minimize lines of code.&lt;br /&gt;
&lt;br /&gt;
===Terms===&lt;br /&gt;
To read this document, you will need to understand a few concepts beforehand:&lt;br /&gt;
*&amp;lt;tt&amp;gt;BRANCHING&amp;lt;/tt&amp;gt; - When the processor takes a different path of code.  For example, to call a function or to use an if statement, the processor will &amp;quot;branch&amp;quot;.  Modern processors attempt to predict pathways with &amp;quot;branch prediction&amp;quot;, but it's best to avoid branching a lot if possible.&lt;br /&gt;
*&amp;lt;tt&amp;gt;STACK ALLOCATION&amp;lt;/tt&amp;gt; - In Pawn, all local data is stored on the stack, a big chunk of continuous memory.  Whenever you create a variable on the stack, it is automatically written with zeroes.&lt;br /&gt;
*&amp;lt;tt&amp;gt;HEAP ALLOCATION&amp;lt;/tt&amp;gt; - In Pawn, temporary data that needs to be referenced by a native is stored on the heap, another area of contiguous, but less restrictive memory.&lt;br /&gt;
*&amp;lt;tt&amp;gt;DATA SECTION&amp;lt;/tt&amp;gt; - This is an area of memory built into your .amxx file.  In fact, it &amp;quot;becomes&amp;quot; the heap at load time.  All your strings and arrays are hardcoded into this area.&lt;br /&gt;
*&amp;lt;tt&amp;gt;EXPENSIVENESS&amp;lt;/tt&amp;gt; - To be &amp;quot;expensive&amp;quot; in computer science means an operation requires a lot of CPU processing.  It usually does not refer to memory size, only to processing cycles and time.  Addition is inexpensive, floating power operations are expensive.  However, both are inexpensive in comparison to writing a file.  An inexpensive operation can also be called &amp;quot;cheap&amp;quot;.&lt;br /&gt;
*&amp;lt;tt&amp;gt;BIG-OH NOTATION&amp;lt;/tt&amp;gt; - O(*) notation refers to the expensiveness of an algorithm.  If something is O(n), it occurs in linear time -- meaning that for N items, it will complete relative to N.  O(N^2) means with N items, it will complete relative to N^2.  O(1) means &amp;quot;constant time&amp;quot; - no matter what N is, it will run in the same amount of time.&lt;br /&gt;
&lt;br /&gt;
==Compiler Optimizations==&lt;br /&gt;
These optimizations have to do with changing how your code is compiled.  While the syntax may remain the same, you are not only increasing compile time, but increasing your plugin's efficiency and speed at run time.&lt;br /&gt;
&lt;br /&gt;
===Always Save Results===&lt;br /&gt;
Observe the example code snippet below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (get_user_team(player) == TEAM_T)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (get_user_team(player) == TEAM_CT) {&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (get_user_team(player) == TEAM_SPECTATOR) {&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This is a mild example of &amp;quot;cache your results&amp;quot;.  When the compiler generates assembly for this code, it will (in pseudo code) generate:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Notice the problem?  We have called &amp;lt;tt&amp;gt;get_user_team&amp;lt;/tt&amp;gt; an extra two times than necessary.  The result doesn't change, so we can save it.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = get_user_team(player)&lt;br /&gt;
if (team == TEAM_T)&lt;br /&gt;
{&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (team == TEAM_CT) {&lt;br /&gt;
    //...code&lt;br /&gt;
} else if (team == TEAM_SPECTATOR) {&lt;br /&gt;
    //...code&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Now, the compiler will only generate this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
  COMPARE+BRANCH&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If &amp;lt;tt&amp;gt;get_user_team&amp;lt;/tt&amp;gt; were an expensive operation (it's relatively cheap), we would have recalculated the entire result each branch of the &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.&lt;br /&gt;
&lt;br /&gt;
===Switch instead of If===&lt;br /&gt;
If you can, you should use &amp;lt;tt&amp;gt;switch&amp;lt;/tt&amp;gt; cases instead of &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;.  This is because for an if statement, the compiler must branch to each consecutive &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; case.  Using the example from above, observe the switch version:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new team = get_user_team(player)&lt;br /&gt;
switch (team)&lt;br /&gt;
{&lt;br /&gt;
  case TEAM_T:&lt;br /&gt;
     //code...&lt;br /&gt;
  case TEAM_CT:&lt;br /&gt;
     //code...&lt;br /&gt;
  case TEAM_SPECTATOR:&lt;br /&gt;
     //code...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will generate what's called a &amp;quot;case table&amp;quot;.  Rather than worm through displaced &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; tests, the compiler generates a table of possible values, which the virtual machine knows to browse through:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  CALL get_user_team&lt;br /&gt;
  COMPARE&lt;br /&gt;
  COMPARE&lt;br /&gt;
  COMPARE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Don't Re-index Arrays===&lt;br /&gt;
A common practice in Small is to &amp;quot;save space&amp;quot; by re-indexing arrays.  There are a few myths behind this, such as saving memory, assuming the compiler does it for you, or readability.  Fact: none of these are true.  Observe the code below:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new players[32], num, team&lt;br /&gt;
get_players(players, num)&lt;br /&gt;
for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   if (!is_user_connected(players[i]))&lt;br /&gt;
      continue;&lt;br /&gt;
   team = get_user_team(players[i])&lt;br /&gt;
   set_user_frags(players[i], 0)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
For this, the compiler generates code similar to:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL is_user_connected&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL get_user_team&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   CALL set_user_frags&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
See what happened?  The compiler does not cache array indexing.  Because we've used &amp;lt;tt&amp;gt;players[i]&amp;lt;/tt&amp;gt; each time, every instance generates 4-6 (or more) instructions which load &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt;, the address of &amp;lt;tt&amp;gt;players&amp;lt;/tt&amp;gt;, computes the final location, and then grabs the data out of memory.  It is much faster to do:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new player&lt;br /&gt;
for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   player = players[i]&lt;br /&gt;
   if (!is_user_connected(player))&lt;br /&gt;
      continue;&lt;br /&gt;
   team = get_user_team(player)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Not only is this more readable, but look at how much cruft we've shaved off the compiler's generated code:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
:LOOP_BEGIN&lt;br /&gt;
   LOAD i&lt;br /&gt;
   LOAD players&lt;br /&gt;
   CALC&lt;br /&gt;
   LOAD players[i]&lt;br /&gt;
   STORE player&lt;br /&gt;
   CALL is_user_connected&lt;br /&gt;
   LOAD player&lt;br /&gt;
   CALL get_user_team&lt;br /&gt;
   LOAD player&lt;br /&gt;
   CALL set_user_frags&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In a large loop you can drastically reduce codesize in this manner.&lt;br /&gt;
&lt;br /&gt;
===Global vs Local and Variables in Loops===&lt;br /&gt;
It is important to realize that every variable in [[Pawn]] is automatically zeroed.  For global variables, they are static and permanent, thus they are zeroed when your plugin is loaded.  Variables in functions, however, must be zeroed dynamically.  This is a slow and tedious operation, and you should not only avoid relying on it when necessary, but you should keep that fact in mind when using arrays.&lt;br /&gt;
&lt;br /&gt;
[[Arrays]] in [[Pawn]] are &amp;quot;cells&amp;quot; of data.  Each cell is four or eight bytes, depending on whether your processor is 32bit or 64bit.  To create an array of 4096 cells, for example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new array[4096]&amp;lt;/pawn&amp;gt;&lt;br /&gt;
The compiler generates code to manually zero every single one of the 16,384 bytes in that location.  Normally, this isn't too bad -- but it can be absolutely deadly in a function which is called quite often.  For example, &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; is called on every [[server tick]] in [[AMX Mod X]].  To declare an array of that size in &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; is highly unnecessary.  Instead, you can take advantage of the fact that not only are globals free of charge, but &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; does not need to be re-entrant.  That is, you will never call &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt; inside of &amp;lt;tt&amp;gt;server_frame&amp;lt;/tt&amp;gt;, so making the variable global will not bring up the problem of one instance of the function overwriting data from another instance of the same function.  Observe:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new g_serverframe_array[4096]&lt;br /&gt;
public server_frame()&lt;br /&gt;
{&lt;br /&gt;
  //...code that uses g_serverframe_array&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will execute conseridably faster.  You can do this with smaller arrays too.&lt;br /&gt;
&lt;br /&gt;
Likewise, it is equally important to avoid declaring arrays inside of loops.  Consider the following block of code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   new message[255], name[32], player&lt;br /&gt;
   player = players[i]&lt;br /&gt;
   get_user_name(player, name, 31)&lt;br /&gt;
   format(message, 254, &amp;quot;Hello, %s&amp;quot;, name)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
If there are 32 players, this loop will actually resize and zero out over 1K of memory thirty two times in a row.  Not good!  However, on the other hand, it's nice that the message is zeroed out for us each time.  &amp;lt;tt&amp;gt;Tip:&amp;lt;/tt&amp;gt; you often only need to zero out the first character of a string.  This will make the entire string empty.  The code below is much more efficient:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new message[255], name[32], player&lt;br /&gt;
for (new i=0; i&amp;lt;num; i++)&lt;br /&gt;
{&lt;br /&gt;
   player = players[i]&lt;br /&gt;
   name[0] = '^0'&lt;br /&gt;
   message[0] = '^0'&lt;br /&gt;
   get_user_name(player, name, 31)&lt;br /&gt;
   format(message, 254, &amp;quot;Hello, %s&amp;quot;, name)&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This has the effect of safely making the string empty beforehand, as well as largely reducing a lot of run-time overhead.&lt;br /&gt;
&lt;br /&gt;
===Static vs Global===&lt;br /&gt;
An alternative to global variables is static variables, which are internally the same but easier to work with for programming.&lt;br /&gt;
&lt;br /&gt;
A variable declared with the keyword &amp;quot;static&amp;quot; instead of &amp;quot;new&amp;quot; operates in the same way a global does (it is created only once) but the variable is local to the function; this means the code is much easier to read, while drastically improving speed just like a global variable.  Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;stock SomeBigFunction()&lt;br /&gt;
{&lt;br /&gt;
   static gaben[255];&lt;br /&gt;
   format(gaben, &amp;quot;%L&amp;quot;, LANG_SERVER, &amp;quot;STUFF&amp;quot;);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This has the same effect as declaring &amp;lt;tt&amp;gt;gaben&amp;lt;/tt&amp;gt; as global, except only &amp;lt;tt&amp;gt;SomeBigFunction&amp;lt;/tt&amp;gt; can use it.  &lt;br /&gt;
&lt;br /&gt;
{{qnotice|Be careful of re-entrancy!}}&lt;br /&gt;
When a variable is static, it has the same re-entrancy problems of a global variable.  That means, if your function might be called recursively, or twice in the same stack frame, you should not use static variables.  This is most often the case for API provided to other plugins or helper functions.  Triggered events are usually never called twice on the same execution chain.&lt;br /&gt;
&lt;br /&gt;
===Constant variables===&lt;br /&gt;
You can declare a variable &amp;quot;constant&amp;quot; by adding the &amp;quot;const&amp;quot; keyword before the variable name:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new const AMX_GABEN[] = &amp;quot;amx_gaben&amp;quot;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What this does is prevents the variable from being changed; essentially, you've locked the variable to a certain value. In this way, a constant can offer a type safe method of simplifying code, unlike a define, which is not type safe.&lt;br /&gt;
&lt;br /&gt;
In addition, constant variables are often optimized out, resulting in quicker and smaller code.&lt;br /&gt;
&lt;br /&gt;
===For Loop Comparisons===&lt;br /&gt;
A common mistake is to write code like this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new string[256] = &amp;quot;something long&amp;quot;&lt;br /&gt;
for (new i=0; i&amp;lt;strlen(string); i++)&lt;br /&gt;
   //...code&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This plays off a similar principle from before: cache results.  The compiler will actually recompute your string length on each iteration of the loop.  This will have even worse effects if your string changes mid-loop.  A more sensible method is:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new string[256] = &amp;quot;something long&amp;quot;&lt;br /&gt;
new len = strlen(string)&lt;br /&gt;
for (new i=0; i&amp;lt;len; i++)&lt;br /&gt;
   //...code&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Tips and Tricks==&lt;br /&gt;
===Lookup Tables===&lt;br /&gt;
Precompute what can be precomputed.  For example, say you have a mapping of weapon indices to names:&lt;br /&gt;
&amp;lt;pawn&amp;gt;if (weapon == CSW_AK47)&lt;br /&gt;
   copy(name, len, &amp;quot;weapon_ak47&amp;quot;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
Ignoring the fact that we have &amp;lt;tt&amp;gt;get_weapon_name&amp;lt;/tt&amp;gt; in [[AMX Mod X]], this is inefficient.  We could precompute this result in a table:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new g_WeaponNamesTable[TOTAL_WEAPONS][] = {&lt;br /&gt;
   //..0 to CSW_AK47-1&lt;br /&gt;
   &amp;quot;weapon_ak47&amp;quot;,&lt;br /&gt;
   //..CSW_AK47+1 to TOTAL_WEAPONS-1&lt;br /&gt;
};&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Perfect Hashing===&lt;br /&gt;
:TODO: explain this&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Local Strings===&lt;br /&gt;
The [[Pawn]] compiler does not optimize the DATA section, which stores all hardcoded strings and global arrays.  If you reference the same hardcoded string 500 times in your plugin, it will appear 500 different times.  If this seems bad enough, it actually does this with all strings.  For example, the empty string (&amp;quot;&amp;quot;) appears everywhere in the include files, usually used as a default parameter to many natives.  This too is copied into the data section for each unique reference.  &lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;set_cvar_num(&amp;quot;amx_gaben&amp;quot;, get_cvar_num(&amp;quot;amx_gaben&amp;quot;) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
This will create two copies of &amp;quot;amx_gaben&amp;quot; in the DATA section.  While this doesn't really hurt, it does increase the size of your plugin.  &lt;br /&gt;
&lt;br /&gt;
Similarly, this has the same problem:&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define AMX_GABEN &amp;quot;amx_gaben&amp;quot;&lt;br /&gt;
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
The only way to avoid this mess is to use global variables.  As stated earlier, they're basically free storage.&lt;br /&gt;
&amp;lt;pawn&amp;gt;new AMX_GABEN[] = &amp;quot;amx_gaben&amp;quot;&lt;br /&gt;
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Again, while not necessary, this will reduce your plugin's size in memory and on disk.  If you're already using defines, you can make this switch easily.&lt;br /&gt;
&lt;br /&gt;
In order to prevent this from changing, you may want to declare it constant:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new const AMX_GABEN[] = &amp;quot;amx_gaben&amp;quot;&lt;br /&gt;
set_cvar_num(AMX_GABEN, get_cvar_num(AMX_GABEN) + 1)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now it is a perfectly safe method of storage.&lt;br /&gt;
&lt;br /&gt;
==Faster Natives==&lt;br /&gt;
AMX Mod X replaces many of the old AMX Mod natives with faster versions.  Read below to discover them.&lt;br /&gt;
&lt;br /&gt;
===Cvar Pointers===&lt;br /&gt;
As of AMX Mod X 1.70, you can cache &amp;quot;cvar pointers&amp;quot;.  These are direct accesses to cvars, rather than named access.  This is a critical optimization which is dozens of times faster.  For example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new g_enabled = register_cvar(&amp;quot;csdm_enabled&amp;quot;, &amp;quot;1&amp;quot;)&lt;br /&gt;
//OR&lt;br /&gt;
new g_enabled = get_cvar_pointer(&amp;quot;csdm_enabled&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
stock SetCSDM(num)&lt;br /&gt;
   set_pcvar_num(g_enabled, num)&lt;br /&gt;
&lt;br /&gt;
stock GetCSDM()&lt;br /&gt;
   return get_pcvar_num(g_enabled)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
All of the cvar* functions (except for set_cvar_string) are mapped to [get|set]_pcvar_*.  You can get a cached cvar pointer with get_cvar_pointer() or register_cvar().&lt;br /&gt;
&lt;br /&gt;
===FormatEX===&lt;br /&gt;
As of AMX Mod X 1.70, there is an ultra high-speed version of format() called formatex().  It skips copy-back checking, unlike format().  formatex() cannot be used if a source input is the same as the output buffer.  For example, these are invalid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new buffer[255]&lt;br /&gt;
formatex(buffer, 254, &amp;quot;%s&amp;quot;, buffer);&lt;br /&gt;
formatex(buffer, 254, buffer);&lt;br /&gt;
formatex(buffer, 254, &amp;quot;%d %s&amp;quot;, buffer[2]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It should be noted that format() will behave the same as formatex() if it detects that there will be no copy-back needed.  However, formatex() does not check this, and thus is slightly faster for situations where the coder is sure of its usage.&lt;br /&gt;
&lt;br /&gt;
===File Writing===&lt;br /&gt;
As of AMX Mod X 1.70, there are new natives for file writing.  Read_file and write_file are O(n^2) functions for consecutive read/writes.  fopen(), fgets(), fputs(), and fclose() are O(n) (or better) depending on how you use them.&lt;br /&gt;
&lt;br /&gt;
[[Category:Scripting (AMX Mod X)]]&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:P34CH_34732&amp;diff=4462</id>
		<title>User:P34CH 34732</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:P34CH_34732&amp;diff=4462"/>
		<updated>2007-04-12T08:32:49Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:''&amp;quot;Good morning! How much does that weigh?&amp;quot;&lt;br /&gt;
:''&amp;quot;Ham!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:''&amp;quot;These beefs are tender. And the exuberance?&amp;quot;&lt;br /&gt;
:''&amp;quot;Insubstantial!&amp;quot;&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:P34CH_34732&amp;diff=4461</id>
		<title>User:P34CH 34732</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:P34CH_34732&amp;diff=4461"/>
		<updated>2007-04-12T08:30:33Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: New page: :'&amp;quot;Good morning! How much does that weigh?&amp;quot;' :'&amp;quot;Ham!&amp;quot;'   :'&amp;quot;These beefs are tender. And the exuberance?&amp;quot;' :'&amp;quot;Insubstantial!&amp;quot;'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:'&amp;quot;Good morning! How much does that weigh?&amp;quot;'&lt;br /&gt;
:'&amp;quot;Ham!&amp;quot;'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:'&amp;quot;These beefs are tender. And the exuberance?&amp;quot;'&lt;br /&gt;
:'&amp;quot;Insubstantial!&amp;quot;'&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:Greentryst/Uncyc/Turtle&amp;diff=4460</id>
		<title>User:Greentryst/Uncyc/Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:Greentryst/Uncyc/Turtle&amp;diff=4460"/>
		<updated>2007-04-12T07:56:25Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: Updated to a more recent version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''turtle''' is an [[bisexual|amphibious]] [[animal]] with an armored [[tank|shell]], an M1 [[penis|helmet]], night-vision [[goggles]], an [[AK-47]] assault [[rifle]], a nasty disposition, and &amp;lt;strike&amp;gt;great sharp teeth&amp;lt;/strike&amp;gt; a cute little [[tail]].  &lt;br /&gt;
&lt;br /&gt;
==Lots of Turtles==&lt;br /&gt;
There are [[billions and billions]] of species of turtles in the world, ranging in size from the genetically engineered 90 nanometer Metal-Oxide-Semiconducting Field Effect Turtle of [[Japan]], to the thunderous fire-breathing 10,000 meter [[Godzilla|Turtlezilla]], also of Japan.  In fact, Japan is practically overrun with turtles of all sizes, because turtles play a vital role in the [[Shinto]] religion (which are sacrificed in great numbers to the Shinto [[god]] [[Godzilla|Turtlezilla]] in order to persuade him not to eat [[Tokyo]]).&lt;br /&gt;
&lt;br /&gt;
==Natural Enemies==&lt;br /&gt;
Turtles, being some of nature's fiercest [[humans|predators]], have few natural enemies.  Of this small, elite group of cyborg animals, however, is the pirate [[bear]] and of course [[cabbage]].  While most bears are docile creatures from the fish kingdom, pirate [[bears]] feed plentifully on the jewel encrusted turtles of the [[Mediterranean]].  These specific turtles provide the basic nutrients necessary to power a bear's [[boob|warp core]]. Human natural enemies are THE GUJU and this big green hotdog. &lt;br /&gt;
&lt;br /&gt;
==Celebrities who swallowed a turtle in early childhood==&lt;br /&gt;
&lt;br /&gt;
*[[Chuck Norris]] (See also: [[Teenage Mutant Ninja Turtles]])&lt;br /&gt;
*[[Oscar Wilde]]&lt;br /&gt;
*[[Keith Chegwin]]&lt;br /&gt;
*[[Michael Jackson]]&lt;br /&gt;
*[[Jack Bauer]]&lt;br /&gt;
*Ozzy&lt;br /&gt;
*Mr. Potato Head&lt;br /&gt;
*Santa Claus&lt;br /&gt;
*Bob Dole&lt;br /&gt;
*The Gujurati&lt;br /&gt;
*Fudge&lt;br /&gt;
&lt;br /&gt;
==Lots of Even More Turtles==&lt;br /&gt;
*In [[1973]], [[Stephen Hawking]] theorized that turtles play a major role in cosmology.  His proposed model, &amp;quot;Turtles All the Way Down&amp;quot;, combined an [[infinity|infinite]] stack of turtles with the principles of [[general relativity]].  Unfortunately, this [[theory]] had to be scrapped because it turned out to be totally inconsistent with godless [[evolution|evolutionism]] and the laws of [[quantum cheddardynamics]].&lt;br /&gt;
*Turtle is also the title bestowed apon the champion of a &amp;quot;turtle match.&amp;quot;  All participants crawl into seperate sleeping bags, and proceed to pass gas.  The person who can put up with the stench the longest is a Turtle&lt;br /&gt;
*Turtles are also the surname of the Austrian royal family, comprising to the inheriters to the Hapsburg Throne. The family was initially started by the gay dance troupe the &amp;quot;Teenage Mutant Ninja Turtles&amp;quot; and their incestuous latvian accountant Master Splinter. To celebrate the founding of the family, Splinter transformed into a rat (as is customary in Latvia)&lt;br /&gt;
*The [[Earth]] rests upon the back of a huge turtle, which in turn rests on the back of another huge turtle.  Turtles-turtles-turtles, all the way!&amp;quot;&lt;br /&gt;
*Turtles are the Truth. Turtles are therefore the guiding principle of every star-fleet officer, according to [[Captain Picard.]]&lt;br /&gt;
&lt;br /&gt;
==Cooking with Turtles==&lt;br /&gt;
Turtles are the primary ingredient of Turtle Soup.  &lt;br /&gt;
&lt;br /&gt;
===Turtle Soup===&lt;br /&gt;
*4 quarts boiling [[water]]&lt;br /&gt;
*3 medium-sized [[potato|potatoes]] (diced)&lt;br /&gt;
*1 cup minced [[onion]]&lt;br /&gt;
*2 tablespoons [[olive oil]]&lt;br /&gt;
*1 teaspoon [[salt]]&lt;br /&gt;
*1 clove [[garlic]] (carded)&lt;br /&gt;
*1 pinch [[MSG|monosodium glutamate]]&lt;br /&gt;
*1 bay leaf&lt;br /&gt;
*1 large live turtle&lt;br /&gt;
&lt;br /&gt;
The important thing is not to use the turtle, because if you use any part of the turtle its fellow turtles will find out and they will come for you in the night. Via your sock drawer.&lt;br /&gt;
Anyway, don't use the turtle. Instead you may substitute any kind of meat, but prime tarantula steak is best. Simmer for approximately 2 hours until the potatoes are moderately soft and the steak looks like something a human would want to eat.  Serves 4.&lt;br /&gt;
&lt;br /&gt;
==How to recognise a turtle==&lt;br /&gt;
It's like a flat snail, but round.&lt;br /&gt;
&lt;br /&gt;
Usually drives a Douche Trough.&lt;br /&gt;
&lt;br /&gt;
Proudly boasts about its future success, which will never be achieved under any circumstances ever.&lt;br /&gt;
&lt;br /&gt;
Can also be identified by asking the following question:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Are you a turtle?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If they respond with the following statement they are.  If anything else is said, they are NOT a turtle&lt;br /&gt;
&lt;br /&gt;
&amp;quot;You bet your sweet @$$ I am!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
*[[Awkward Turtle]] &lt;br /&gt;
*[[Nazi turtle]]&lt;br /&gt;
*[[Animal sacrifice]]&lt;br /&gt;
*[[Gravity]]&lt;br /&gt;
*[[Cooking]]&lt;br /&gt;
*[[Turtle Washers anonymous]]&lt;br /&gt;
*[[User:Tompkins|Tompkins]]&lt;br /&gt;
[[category:Reptiles]]&lt;br /&gt;
[[category:Food]]&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Turtle&amp;diff=4459</id>
		<title>Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Turtle&amp;diff=4459"/>
		<updated>2007-04-12T07:51:46Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: Redirecting to User:Greentryst/Uncyc/Turtle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[User:Greentryst/Uncyc/Turtle]]&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Turtle&amp;diff=4458</id>
		<title>Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Turtle&amp;diff=4458"/>
		<updated>2007-04-12T07:50:44Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: New page: #REDIRECT [http://uncyclopedia.org/wiki/Turtle]&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [http://uncyclopedia.org/wiki/Turtle]&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Recursion&amp;diff=4457</id>
		<title>Recursion</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Recursion&amp;diff=4457"/>
		<updated>2007-04-12T07:39:50Z</updated>

		<summary type="html">&lt;p&gt;P34CH 34732: New page: See &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://wiki.alliedmods.net/Recursion Recursion]&amp;lt;/span&amp;gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;See &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://wiki.alliedmods.net/Recursion Recursion]&amp;lt;/span&amp;gt;.&lt;/div&gt;</summary>
		<author><name>P34CH 34732</name></author>
		
	</entry>
</feed>