(***********************************************************************
Mathematica-Compatible Notebook
This notebook can be used on any computer system with Mathematica 3.0,
MathReader 3.0, or any compatible application. The data for the notebook
starts with the line of stars above.
To get the notebook into a Mathematica-compatible application, do one of
the following:
* Save the data starting with the line of stars above into a file
with a name ending in .nb, then open the file inside the application;
* Copy the data starting with the line of stars above to the
clipboard, then use the Paste menu command inside the application.
Data for notebooks contains only printable 7-bit ASCII and can be
sent directly in email or through ftp in text mode. Newlines can be
CR, LF or CRLF (Unix, Macintosh or MS-DOS style).
NOTE: If you modify the data for this notebook not in a Mathematica-
compatible application, you must delete the line below containing the
word CacheID, otherwise Mathematica-compatible applications may try to
use invalid cache data.
For more information on notebooks and Mathematica-compatible
applications, contact Wolfram Research:
web: http://www.wolfram.com
email: info@wolfram.com
phone: +1-217-398-0700 (U.S.)
Notebook reader applications are available free of charge from
Wolfram Research.
***********************************************************************)
(*CacheID: 232*)
(*NotebookFileLineBreakTest
NotebookFileLineBreakTest*)
(*NotebookOptionsPosition[ 30822, 1024]*)
(*NotebookOutlinePosition[ 31905, 1059]*)
(* CellTagsIndexPosition[ 31861, 1055]*)
(*WindowFrame->Normal*)
Notebook[{
Cell[CellGroupData[{
Cell[TextData[" 22. Compilation"], "Title",
Evaluatable->False,
AspectRatioFixed->True],
Cell["Last revision: April 15 1998", "SmallText",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Here we explore the notion of compilation, focussing on demonstrating the \
advantage in speed and the limitation of using atomic data types to represent \
machine-precision numbers."], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[" operations/structures introduced: \n",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox[" Compile[]\n ",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["inline functions",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier",
FontSlant->"Italic"]
}], "SmallText",
Evaluatable->False,
AspectRatioFixed->True],
Cell[CellGroupData[{
Cell[TextData["Compilation"], "Section",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
"Recall that compiled programs have one overarching advantage: the great \
reduction in execution time. Recall also that using machine-size integers \
and approximations also affords the user a great reduction in execution time. \
For these reason, practically every computer application which you execute \
is using a compiled, rather than interpreted, program, one which uses \
machine-size integers and approximations whenever possible. For instance, ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" itself is such a program. We have not yet been able to write our own \
compiled \"programs\" requiring machine-size numbers because ",
StyleBox["Mathematica",
FontSlant->"Italic"],
"'s standard mode is to interpret all commands statement-by-statement and \
to evaluate all expressions with as much accuracy as possible. We can \
explore compilation and the use of machine-size numbers, however, by having ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" compile particular functions."
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[" permits the compilation of ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[" code using the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Compile[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" function. The \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Compile[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" function takes a sequence of ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
" expressions and converts them to a language very similar to machine \
language, a language which the computer can execute much faster, thereby \
mimicing actual compilation. In order to use the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Compile[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\" function, however, we must decide what the data types of the parameters \
are, and we are limited to \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["_Integer",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" (machine-size integer), \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["_Real",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" (machine-precision approximate real number), and \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["True|False",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" (a boolean value). [",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Complex",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
" numbers are also permitted.] Compiled functions, because they use the \
internal language of computers, are not permitted to take advantage of ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
"'s predefined structured data types such as lists and patterns. If we \
insist on using such structures, some intermediary must transform the \
structures back to these machine data types, by breaking a list into its \
component pieces, breaking huge integers into smaller machine-size pieces, \
and so on. In a compiled setting, we would have to decide ourselves how to \
represent lists as sequences of machine-size integers, how to represent a \
string as a sequence of characters, and so forth, and such decisions form the \
basis for a course in data structures and algorithms.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["The syntax for the basic \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Compile[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" command is \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Compile[list,expr]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\", where \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["list",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\" is either a list of single names, which represent parameters of data \
type \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["_Real",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\", or a list of pairs consisting of a name and a data type selected from \
the ones above, and where \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["expr",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" is some ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
" expression. For example, suppose we'd like a function to compute \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["x^y",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\", where \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["x",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" and \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["y",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" are assumed to be names of type ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Real",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Delphian"],
StyleBox[":",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["myPower = Compile[{x,y},x^y]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["We could have specified that \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["x",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" be considered of type ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Real",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[" and \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["y",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" a machine-size integer by writing instead",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["myPowInt = Compile[{{x,_Real},{y,_Integer}},x^y]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["It is important that we use the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Set",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" operator \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["=",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" and not the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["SetDelayed",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" operator \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox[":=",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\", for the latter will perform the compilation only after the function is \
called, not before, and in what follows we will want to time the function \
without counting the time of compilation.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[CellGroupData[{
Cell[TextData["Comparing Speed with myPower"], "Subsection",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["Here we submit compiled functions and standard ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
" interpreted functions to a head-to-head test. The operations we include \
in the functions are standard arithmetic functions, which are the real \
strength of compiled programs, instead of \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Plot[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\" calls or complicated list-based functions. Our first attempt is to \
define a function \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["myPower",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" which is a compiled version of \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["myPower2",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\", both of which take two arguments, presumed ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Real",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
", and raise the first argument to the second. We then compare their \
timings when the arguments are \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["2.0",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" and \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["3.0",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\".",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Clear[myPower,myPower2]\nmyPower = Compile[{x,y},x^y]\nmyPower2[x_,y_] := \
x^y"], "Input",
AspectRatioFixed->True],
Cell[TextData["Timing[myPower[2.0,3.0]]\nTiming[myPower2[2.0,3.0]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"Execute the above cell a couple of times to insure that you are not \
getting exceptional timings; the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Timing[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\" function can sometimes give answers which are too small or negative, \
because the actual time to execute the function is too small to measure. \
After executing the functions several times, however, you may have become \
convinced that it is difficult to tell the difference between functions which \
execute so quickly. In order to get a better idea, we'll have each of the \
functions executed 10000 times, using the ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[" command \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Do[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\".",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Timing[Do[myPower[2.0,3.0],{10000}]]\n\
Timing[Do[myPower2[2.0,3.0],{10000}]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"Now the difference should be clear. The compiled version executes more \
than twice as quickly as the interpreted version. Now notice that we're \
using an interpreted \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Do[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\" command to call the compiled function. How would the timing speed up \
if we compiled the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Do[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" inside the function?",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Clear[myPower3]\nmyPower3 = Compile[{x,y},Do[x^y,{10000}]]\n\
Timing[myPower3[2.0,3.0]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["The conclusion: compiling the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Power",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" operator \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["^",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" and the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Do[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" command both speed up the functions by a remarkable amount.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True]
}, Closed]],
Cell[CellGroupData[{
Cell[TextData["Data Type Checking in Compiled Functions"], "Subsection",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
"What if you give a compiled function values for the parameters which do \
not match the required data types? Unlike most languages, ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" prevents us from encountering a serious error in this situation. First, \
it tries to convert the values to the desired values, for instance by \
converting integers to approximations. Second, if it cannot convert, or \
reaches an error in the calculation using the compiled code, ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" simply reverts to evaluating the original expression---in its standard \
interpreted mode. One consequence is that is never hurts to compile a \
function in ",
StyleBox["Mathematica",
FontSlant->"Italic"],
", since if the data type values don't match, ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" simply executes the function in its normal fashion anyway. Let's look at \
some associated timings."
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Clear[myPower,myPower2]\nmyPower = Compile[{x,y},Do[x^y,{10000}];x^y]\n\
myPower2[x_,y_] := (Do[x^y,{10000}];x^y)"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"Note that the two functions now have a return value, namely, the value of \
\"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["x^y",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\".",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["Timing[myPower[2.0,3.0]]\nTiming[myPower2[2.0,3.0]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"Here the timings are as we would expect, and the return values are \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["8.",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\".",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["Timing[myPower[2,3]]\nTiming[myPower2[2,3]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"In the timings above, we see that the timings are still in favor of the \
compiled version, indicating that the compiled version was executed, but we \
also note that \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["2",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" and \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["3",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" were converted to ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Real",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
" data (the default for parameters of compiled functions), since the result \
from the compiled version is \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["8.",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\", not \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["8",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\".",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["Finally, we'll give ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[" some numbers which ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[" can't handle in machine-precision: we'll ask for ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["10^1000",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
", which is outside the range of machine-precision real numbers, and, for \
that matter, machine-size integers, too.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["Timing[myPower[10,1000]]\nTiming[myPower2[10,1000]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
"Note that the compiled version actually took longer, because the compiled \
code was attempted first, resulting in an error, and the ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" interpreted code was then used."
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["It is interesting to note that many ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
" functions actually compile a function they are given before they use the \
function over and over again. One example is \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Plot[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\"; instead of plotting 1000 points, say, and having to interpret the \
function 1000 times, ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
" compiles it first. To see the difference, we can explicitly instruct \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Plot[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" not to compile. Here are two examples.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Timing[Plot[Sin[x],{x,0,1},PlotPoints->1000,\nCompiled->False]]"], "Input",
AspectRatioFixed->True],
Cell[TextData["Timing[Plot[Sin[x],{x,0,1},PlotPoints->1000]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[
"(We use 1000 points in the plots in order to witness a significant \
difference in the timings.) "], "Text",
Evaluatable->False,
AspectRatioFixed->True]
}, Closed]],
Cell[CellGroupData[{
Cell[TextData["Taking a Look at Compiled Code"], "Subsection",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"To gain a better idea of just what \"machine language\" looks like, we'll \
ask ",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Mathematica",
Evaluatable->False,
AspectRatioFixed->True,
FontSlant->"Italic"],
StyleBox[
" to produce the compiled code for a compiled function. We need only use \
the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["?",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" command.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Clear[myPower]\nmyPower = Compile[{x,y},Do[x^y,{10000}];x^y];\n?myPower"],
"Input",
AspectRatioFixed->True],
Cell[TextData[{
"As we see, the internal format of a compiled function is a list which \
contains, first, a list of the assumed data types, then a list of \"registers\
\" that will be used in the code, followed by a list of computer \
\"instructions\" given in a certain code, and finally the ",
StyleBox["Mathematica",
FontSlant->"Italic"],
" function that will be executed if the compiled code fails or is \
inappropriate for the data. One could decipher the compiled code, using \
information in Wolfram Research's technical reports on compiled code, but our \
interest here is to understand the idea of machine language without \
understanding how to program in machine language. "
}], "Text",
Evaluatable->False,
AspectRatioFixed->True]
}, Closed]],
Cell[CellGroupData[{
Cell[TextData["Inline Functions"], "Subsection",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
"Recall that we learned that inline functions were faster than functions \
called under standard function calls. Let's take a look at the \
time/length-of-code tradeoff. We confess at the outset that anonymous \
functions, which share syntactical similarities with inline functions as used \
in other languages, actually take longer in ",
StyleBox["Mathematica",
FontSlant->"Italic"],
". Instead, we'll implement a true analogue of inline functions, by \
expanding out the function calls ourselves."
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"In practice, remember, inline functions are implemented by eliminating the \
standard function call; the code for the inline function is written directly \
into the compiled code each time the function is referenced. A standard \
function call implementation, on the other hand, requires storing parameters, \
jumping to a different section of compiled code where the function code is \
stored, and finally copying a return value back to the original place--but \
only one copy of the compiled code for the function needs to be stored."],
"Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"We implement a compiled version of a standard function as follows."], "Text",\
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Clear[myPower,myPower2]\nmyPower = Compile[{x,y},x^y]\nmyPower2 = \
Compile[{x,y},Do[myPower[x,y],{100}]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[{
StyleBox["Notice that \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["myPower",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" is compiled and placed in memory somewhere, while \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["myPower2",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" references \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["myPower",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" 100 times, thereby executing a function call 100 times.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"We implement an inline version of the function by simply repeating \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["x^y",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox[
"\" 100 times, thereby eliminating the function call at all, instead \
inserting whatever compiled code is necessary 100 times.",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[
"Clear[myPower3]\nmyPower3 = Compile[{x,y},\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;\n\t\
x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;x^y;]"], "Input",
AspectRatioFixed->True],
Cell[TextData["Now we do a head-to-head test."], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["Timing[myPower2[2.,3.]]"], "Input",
AspectRatioFixed->True],
Cell[TextData["Timing[myPower3[2.,3.]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[
"To make the timing more accurate, let's execute each 100 times."], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["Timing[Do[myPower2[2.,3.],{100}]]"], "Input",
AspectRatioFixed->True],
Cell[TextData["Timing[Do[myPower3[2.,3.],{100}]]"], "Input",
AspectRatioFixed->True],
Cell[TextData[
"A fairly dramatic difference: function calls take time! Now let's look at \
the length of the compiled code. For the standard function call, we have two \
functions:"], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["?myPower"], "Input",
AspectRatioFixed->True],
Cell[TextData["?myPower2"], "Input",
AspectRatioFixed->True],
Cell[TextData[
"For the inline function implementation, we have only one (long) function:"],
"Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData["?myPower3"], "Input",
AspectRatioFixed->True]
}, Closed]],
Cell[CellGroupData[{
Cell[TextData["Notes"], "Subsection",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
StyleBox[
"It is also possible to require that, during compilation of an expressions, \
certain quantities have certain data types, using a third argument to the \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["Compile[]",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\" command; see \"",
Evaluatable->False,
AspectRatioFixed->True],
StyleBox["?Compile",
Evaluatable->False,
AspectRatioFixed->True,
FontFamily->"Courier"],
StyleBox["\".",
Evaluatable->False,
AspectRatioFixed->True]
}], "Text",
Evaluatable->False,
AspectRatioFixed->True],
Cell[TextData[{
"The reason that anonymous functions take just as long, or longer, is that \
",
StyleBox["Mathematica",
FontSlant->"Italic"],
" actually uses them to define a function, complete with necessary function \
calls, instead of copying the expression directly, as an inline function \
implementation would do."
}], "Text",
Evaluatable->False,
AspectRatioFixed->True]
}, Closed]]
}, Closed]]
}, Open ]]
},
FrontEndVersion->"Macintosh 3.0",
ScreenRectangle->{{0, 832}, {0, 604}},
WindowToolbars->{},
WindowSize->{578, 563},
WindowMargins->{{4, Automatic}, {Automatic, 1}},
PrintingCopies->1,
PrintingPageRange->{1, Automatic},
PrivateNotebookOptions->{"ColorPalette"->{RGBColor, -1}},
ShowCellLabel->True,
ShowCellTags->False,
RenderingOptions->{"ObjectDithering"->True,
"RasterDithering"->False},
MacintoshSystemPageSetup->"\<\
00<0004/0B`000003809T?o>old"
]
(***********************************************************************
Cached data follows. If you edit this Notebook file directly, not using
Mathematica, you must remove the line containing CacheID at the top of
the file. The cache data will then be recreated when you save this file
from within Mathematica.
***********************************************************************)
(*CellTagsOutline
CellTagsIndex->{}
*)
(*CellTagsIndex
CellTagsIndex->{}
*)
(*NotebookFileOutline
Notebook[{
Cell[CellGroupData[{
Cell[1731, 51, 91, 2, 98, "Title",
Evaluatable->False],
Cell[1825, 55, 98, 2, 26, "SmallText",
Evaluatable->False],
Cell[1926, 59, 257, 5, 46, "Text",
Evaluatable->False],
Cell[2186, 66, 540, 19, 54, "SmallText",
Evaluatable->False],
Cell[CellGroupData[{
Cell[2751, 89, 88, 2, 50, "Section",
Evaluatable->False],
Cell[2842, 93, 1101, 22, 164, "Text",
Evaluatable->False],
Cell[3946, 117, 3210, 95, 231, "Text",
Evaluatable->False],
Cell[7159, 214, 2217, 81, 101, "Text",
Evaluatable->False],
Cell[9379, 297, 81, 1, 27, "Input"],
Cell[9463, 300, 744, 27, 47, "Text",
Evaluatable->False],
Cell[10210, 329, 101, 1, 27, "Input"],
Cell[10314, 332, 1086, 37, 63, "Text",
Evaluatable->False],
Cell[CellGroupData[{
Cell[11425, 373, 108, 2, 46, "Subsection",
Evaluatable->False],
Cell[11536, 377, 1864, 62, 77, "Text",
Evaluatable->False],
Cell[13403, 441, 133, 3, 40, "Input"],
Cell[13539, 446, 104, 1, 30, "Input"],
Cell[13646, 449, 1203, 35, 77, "Text",
Evaluatable->False],
Cell[14852, 486, 131, 3, 30, "Input"],
Cell[14986, 491, 773, 25, 51, "Text",
Evaluatable->False],
Cell[15762, 518, 141, 3, 40, "Input"],
Cell[15906, 523, 763, 27, 38, "Text",
Evaluatable->False]
}, Closed]],
Cell[CellGroupData[{
Cell[16706, 555, 120, 2, 30, "Subsection",
Evaluatable->False],
Cell[16829, 559, 1034, 23, 90, "Text",
Evaluatable->False],
Cell[17866, 584, 167, 3, 40, "Input"],
Cell[18036, 589, 392, 15, 25, "Text",
Evaluatable->False],
Cell[18431, 606, 104, 1, 30, "Input"],
Cell[18538, 609, 382, 14, 25, "Text",
Evaluatable->False],
Cell[18923, 625, 96, 1, 30, "Input"],
Cell[19022, 628, 1293, 46, 51, "Text",
Evaluatable->False],
Cell[20318, 676, 865, 29, 38, "Text",
Evaluatable->False],
Cell[21186, 707, 104, 1, 30, "Input"],
Cell[21293, 710, 304, 8, 38, "Text",
Evaluatable->False],
Cell[21600, 720, 1205, 40, 64, "Text",
Evaluatable->False],
Cell[22808, 762, 117, 2, 30, "Input"],
Cell[22928, 766, 98, 1, 22, "Input"],
Cell[23029, 769, 172, 4, 25, "Text",
Evaluatable->False]
}, Closed]],
Cell[CellGroupData[{
Cell[23238, 778, 110, 2, 30, "Subsection",
Evaluatable->False],
Cell[23351, 782, 657, 24, 38, "Text",
Evaluatable->False],
Cell[24011, 808, 128, 3, 40, "Input"],
Cell[24142, 813, 757, 14, 77, "Text",
Evaluatable->False]
}, Closed]],
Cell[CellGroupData[{
Cell[24936, 832, 96, 2, 30, "Subsection",
Evaluatable->False],
Cell[25035, 836, 588, 12, 64, "Text",
Evaluatable->False],
Cell[25626, 850, 614, 10, 77, "Text",
Evaluatable->False],
Cell[26243, 862, 143, 4, 25, "Text",
Evaluatable->False],
Cell[26389, 868, 159, 3, 40, "Input"],
Cell[26551, 873, 796, 27, 38, "Text",
Evaluatable->False],
Cell[27350, 902, 509, 16, 38, "Text",
Evaluatable->False],
Cell[27862, 920, 557, 12, 130, "Input"],
Cell[28422, 934, 104, 2, 25, "Text",
Evaluatable->False],
Cell[28529, 938, 76, 1, 22, "Input"],
Cell[28608, 941, 76, 1, 22, "Input"],
Cell[28687, 944, 138, 3, 25, "Text",
Evaluatable->False],
Cell[28828, 949, 86, 1, 22, "Input"],
Cell[28917, 952, 86, 1, 22, "Input"],
Cell[29006, 955, 243, 5, 38, "Text",
Evaluatable->False],
Cell[29252, 962, 61, 1, 22, "Input"],
Cell[29316, 965, 62, 1, 22, "Input"],
Cell[29381, 968, 151, 4, 25, "Text",
Evaluatable->False],
Cell[29535, 974, 62, 1, 22, "Input"]
}, Closed]],
Cell[CellGroupData[{
Cell[29634, 980, 85, 2, 30, "Subsection",
Evaluatable->False],
Cell[29722, 984, 667, 23, 38, "Text",
Evaluatable->False],
Cell[30392, 1009, 390, 10, 64, "Text",
Evaluatable->False]
}, Closed]]
}, Closed]]
}, Open ]]
}
]
*)
(***********************************************************************
End of Mathematica Notebook file.
***********************************************************************)