diff --git a/Manual.ipynb b/Manual.ipynb index 87c2bda..1b171ea 100644 --- a/Manual.ipynb +++ b/Manual.ipynb @@ -1,16 +1,5 @@ { "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "using Revise\n" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -24,24 +13,16 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[1m\u001b[36mINFO: \u001b[39m\u001b[22m\u001b[36mPrecompiling module FProfile.\n", - "\u001b[39m" - ] - }, { "data": { "text/plain": [ - "ProfileData(41 backtraces)" + "ProfileData(40 backtraces)" ] }, - "execution_count": 2, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } @@ -61,16 +42,16 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "ProfileData(982 backtraces)" + "ProfileData(920 backtraces)" ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -83,7 +64,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "`ProfileData` merely wraps the internal data in `Base.Profile`. Do not forget that Julia compiles code the first time a function is run; if you do not want to measure compilation time, execute your code once before profiling." + "Do not forget that Julia compiles code the first time a function is run; if you do not want to measure compilation time, execute your code once before profiling." ] }, { @@ -92,28 +73,28 @@ "source": [ "# Flat view\n", "\n", - "FProfile's `flat` report is a [dataframe](http://juliadata.github.io/DataFrames.jl/stable/man/getting_started/#Getting-Started-1), however no particular knowledge of dataframes is necessary. I'll provide a few common operations below." + "FProfile's `flat` report is a [dataframe](http://juliadata.github.io/DataFrames.jl/stable/man/getting_started/#Getting-Started-1). No particular knowledge of dataframes is necessary. I'll provide a few common operations below." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
count_percentstackframespecializationmethodfilefunctionmodule
199.9execute_request(::ZMQ.Socket, ::IJulia.Msg) at execute_request.jl:154MethodInstance for execute_request(::ZMQ.Socket, ::IJulia.Msg)execute_request(socket, msg) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl:115/Users/cedric/.julia/v0.6/IJulia/src/execute_request.jlIJulia.execute_requestIJulia
299.9anonymous at <missing>:?MethodInstance for missing_info()missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25/Users/cedric/.julia/v0.6/FProfile/src/FProfile.jlFProfile.MissingInfo.missing_infoFProfile.MissingInfo
399.9macro expansion at FProfile.jl:52 [inlined]MethodInstance for missing_info()missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25/Users/cedric/.julia/v0.6/FProfile/src/FProfile.jlFProfile.MissingInfo.missing_infoFProfile.MissingInfo
499.9(::IJulia.##14#17)() at task.jl:335MethodInstance for (::IJulia.##14#17)()(::IJulia.##14#17)() in IJulia at task.jl:335task.jlIJulia.#14IJulia
599.9eventloop(::ZMQ.Socket) at eventloop.jl:8MethodInstance for eventloop(::ZMQ.Socket)eventloop(socket) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl:2/Users/cedric/.julia/v0.6/IJulia/src/eventloop.jlIJulia.eventloopIJulia
" + "
count_pctstackframespecializationmethodfilefunctionmodule
199.89execute_request(::ZMQ.Socket, ::IJulia.Msg) at execute_request.jl:154MethodInstance for execute_request(::ZMQ.Socket, ::IJulia.Msg)execute_request(socket, msg) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl:115/Users/cedric/.julia/v0.6/IJulia/src/execute_request.jlIJulia.execute_requestIJulia
299.89anonymous at <missing>:?MethodInstance for missing_info()missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25/Users/cedric/.julia/v0.6/FProfile/src/FProfile.jlFProfile.MissingInfo.missing_infoFProfile.MissingInfo
399.89macro expansion at FProfile.jl:52 [inlined]MethodInstance for missing_info()missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25/Users/cedric/.julia/v0.6/FProfile/src/FProfile.jlFProfile.MissingInfo.missing_infoFProfile.MissingInfo
499.89(::IJulia.##14#17)() at task.jl:335MethodInstance for (::IJulia.##14#17)()(::IJulia.##14#17)() in IJulia at task.jl:335task.jlIJulia.#14IJulia
599.89eventloop(::ZMQ.Socket) at eventloop.jl:8MethodInstance for eventloop(::ZMQ.Socket)eventloop(socket) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl:2/Users/cedric/.julia/v0.6/IJulia/src/eventloop.jlIJulia.eventloopIJulia
" ], "text/plain": [ "5×7 DataFrames.DataFrame\n", - "│ Row │ count_percent │\n", - "├─────┼───────────────┤\n", - "│ 1 │ 99.9 │\n", - "│ 2 │ 99.9 │\n", - "│ 3 │ 99.9 │\n", - "│ 4 │ 99.9 │\n", - "│ 5 │ 99.9 │\n", + "│ Row │ count_pct │\n", + "├─────┼───────────┤\n", + "│ 1 │ 99.89 │\n", + "│ 2 │ 99.89 │\n", + "│ 3 │ 99.89 │\n", + "│ 4 │ 99.89 │\n", + "│ 5 │ 99.89 │\n", "\n", "│ Row │ stackframe │\n", "├─────┼───────────────────────────────────────────────────────────────────────┤\n", @@ -156,7 +137,7 @@ "│ 5 │ IJulia.eventloop │ IJulia │" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -189,20 +170,20 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
count_percentend_count_percentstackframespecializationmethodfilefunctionmodule
1100.00.0do_computation(::Int64) at In[5]:1MethodInstance for do_computation(::Int64)do_computation(n) in Main at In[5]:1In[5]do_computationMain
2100.0100.0sum_of_sin(::Int64) at In[5]:2MethodInstance for sum_of_sin(::Int64)sum_of_sin(n) in Main at In[5]:2In[5]sum_of_sinMain
" + "
count_pctend_count_pctstackframespecializationmethodfilefunctionmodule
1100.00.0do_computation(::Int64) at In[4]:1MethodInstance for do_computation(::Int64)do_computation(n) in Main at In[4]:1In[4]do_computationMain
2100.0100.0sum_of_sin(::Int64) at In[4]:2MethodInstance for sum_of_sin(::Int64)sum_of_sin(n) in Main at In[4]:2In[4]sum_of_sinMain
" ], "text/plain": [ "2×8 DataFrames.DataFrame\n", - "│ Row │ count_percent │ end_count_percent │ stackframe │\n", - "├─────┼───────────────┼───────────────────┼────────────────────────────────────┤\n", - "│ 1 │ 100.0 │ 0.0 │ do_computation(::Int64) at In[5]:1 │\n", - "│ 2 │ 100.0 │ 100.0 │ sum_of_sin(::Int64) at In[5]:2 │\n", + "│ Row │ count_pct │ end_count_pct │ stackframe │\n", + "├─────┼───────────┼───────────────┼────────────────────────────────────┤\n", + "│ 1 │ 100.0 │ 0.0 │ do_computation(::Int64) at In[4]:1 │\n", + "│ 2 │ 100.0 │ 100.0 │ sum_of_sin(::Int64) at In[4]:2 │\n", "\n", "│ Row │ specialization │\n", "├─────┼────────────────────────────────────────────┤\n", @@ -211,11 +192,11 @@ "\n", "│ Row │ method │ file │ function │ module │\n", "├─────┼──────────────────────────────────────┼───────┼────────────────┼────────┤\n", - "│ 1 │ do_computation(n) in Main at In[5]:1 │ In[5] │ do_computation │ Main │\n", - "│ 2 │ sum_of_sin(n) in Main at In[5]:2 │ In[5] │ sum_of_sin │ Main │" + "│ 1 │ do_computation(n) in Main at In[4]:1 │ In[4] │ do_computation │ Main │\n", + "│ 2 │ sum_of_sin(n) in Main at In[4]:2 │ In[4] │ sum_of_sin │ Main │" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -238,37 +219,37 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
count_percentmethodfilefunctionmodule
199.9include_string(mod::Module, code::String, fname::String) in Compat at /Users/cedric/.julia/v0.6/Compat/src/Compat.jl:464/Users/cedric/.julia/v0.6/Compat/src/Compat.jlinclude_stringCompat
299.9execute_request(socket, msg) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl:115/Users/cedric/.julia/v0.6/IJulia/src/execute_request.jlIJulia.execute_requestIJulia
399.9include_string(txt::String, fname::String) in Base at loading.jl:515loading.jlinclude_stringBase
499.9eventloop(socket) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl:2/Users/cedric/.julia/v0.6/IJulia/src/eventloop.jlIJulia.eventloopIJulia
599.9missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25/Users/cedric/.julia/v0.6/FProfile/src/FProfile.jlFProfile.MissingInfo.missing_infoFProfile.MissingInfo
699.9(::IJulia.##14#17)() in IJulia at task.jl:335task.jlIJulia.#14IJulia
799.59second_derivative(f::Function, x::Number) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl:71/Users/cedric/.julia/v0.6/Calculus/src/derivative.jlCalculus.second_derivativeCalculus
848.37derivative(f::Function, ftype::Symbol, dtype::Symbol) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl:2/Users/cedric/.julia/v0.6/Calculus/src/derivative.jlCalculus.derivativeCalculus
923.32finite_difference_hessian(f::Function, g::Function, x::Number, dtype::Symbol) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jl:224/Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jlCalculus.finite_difference_hessianCalculus
1019.86finite_difference(f::Function, x::T, dtype::Symbol) where T<:Number in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jl:48/Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jlCalculus.finite_differenceCalculus
" + "
count_pctmethodfilefunctionmodule
199.89missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25/Users/cedric/.julia/v0.6/FProfile/src/FProfile.jlFProfile.MissingInfo.missing_infoFProfile.MissingInfo
299.89include_string(txt::String, fname::String) in Base at loading.jl:515loading.jlinclude_stringBase
399.89execute_request(socket, msg) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl:115/Users/cedric/.julia/v0.6/IJulia/src/execute_request.jlIJulia.execute_requestIJulia
499.89(::IJulia.##14#17)() in IJulia at task.jl:335task.jlIJulia.#14IJulia
599.89include_string(mod::Module, code::String, fname::String) in Compat at /Users/cedric/.julia/v0.6/Compat/src/Compat.jl:464/Users/cedric/.julia/v0.6/Compat/src/Compat.jlinclude_stringCompat
699.89eventloop(socket) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl:2/Users/cedric/.julia/v0.6/IJulia/src/eventloop.jlIJulia.eventloopIJulia
799.57second_derivative(f::Function, x::Number) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl:71/Users/cedric/.julia/v0.6/Calculus/src/derivative.jlCalculus.second_derivativeCalculus
853.91derivative(f::Function, ftype::Symbol, dtype::Symbol) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl:2/Users/cedric/.julia/v0.6/Calculus/src/derivative.jlCalculus.derivativeCalculus
919.57finite_difference_hessian(f::Function, g::Function, x::Number, dtype::Symbol) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jl:224/Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jlCalculus.finite_difference_hessianCalculus
1014.67finite_difference(f::Function, x::T, dtype::Symbol) where T<:Number in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jl:48/Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jlCalculus.finite_differenceCalculus
" ], "text/plain": [ "10×5 DataFrames.DataFrame\n", - "│ Row │ count_percent │\n", - "├─────┼───────────────┤\n", - "│ 1 │ 99.9 │\n", - "│ 2 │ 99.9 │\n", - "│ 3 │ 99.9 │\n", - "│ 4 │ 99.9 │\n", - "│ 5 │ 99.9 │\n", - "│ 6 │ 99.9 │\n", - "│ 7 │ 99.59 │\n", - "│ 8 │ 48.37 │\n", - "│ 9 │ 23.32 │\n", - "│ 10 │ 19.86 │\n", + "│ Row │ count_pct │\n", + "├─────┼───────────┤\n", + "│ 1 │ 99.89 │\n", + "│ 2 │ 99.89 │\n", + "│ 3 │ 99.89 │\n", + "│ 4 │ 99.89 │\n", + "│ 5 │ 99.89 │\n", + "│ 6 │ 99.89 │\n", + "│ 7 │ 99.57 │\n", + "│ 8 │ 53.91 │\n", + "│ 9 │ 19.57 │\n", + "│ 10 │ 14.67 │\n", "\n", "│ Row │ method │\n", "├─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤\n", - "│ 1 │ include_string(mod::Module, code::String, fname::String) in Compat at /Users/cedric/.julia/v0.6/Compat/src/Compat.jl:464 │\n", - "│ 2 │ execute_request(socket, msg) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl:115 │\n", - "│ 3 │ include_string(txt::String, fname::String) in Base at loading.jl:515 │\n", - "│ 4 │ eventloop(socket) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl:2 │\n", - "│ 5 │ missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25 │\n", - "│ 6 │ (::IJulia.##14#17)() in IJulia at task.jl:335 │\n", + "│ 1 │ missing_info() in FProfile.MissingInfo at /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl:25 │\n", + "│ 2 │ include_string(txt::String, fname::String) in Base at loading.jl:515 │\n", + "│ 3 │ execute_request(socket, msg) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl:115 │\n", + "│ 4 │ (::IJulia.##14#17)() in IJulia at task.jl:335 │\n", + "│ 5 │ include_string(mod::Module, code::String, fname::String) in Compat at /Users/cedric/.julia/v0.6/Compat/src/Compat.jl:464 │\n", + "│ 6 │ eventloop(socket) in IJulia at /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl:2 │\n", "│ 7 │ second_derivative(f::Function, x::Number) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl:71 │\n", "│ 8 │ derivative(f::Function, ftype::Symbol, dtype::Symbol) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl:2 │\n", "│ 9 │ finite_difference_hessian(f::Function, g::Function, x::Number, dtype::Symbol) in Calculus at /Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jl:224 │\n", @@ -276,12 +257,12 @@ "\n", "│ Row │ file │\n", "├─────┼─────────────────────────────────────────────────────────────┤\n", - "│ 1 │ /Users/cedric/.julia/v0.6/Compat/src/Compat.jl │\n", - "│ 2 │ /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl │\n", - "│ 3 │ loading.jl │\n", - "│ 4 │ /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl │\n", - "│ 5 │ /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl │\n", - "│ 6 │ task.jl │\n", + "│ 1 │ /Users/cedric/.julia/v0.6/FProfile/src/FProfile.jl │\n", + "│ 2 │ loading.jl │\n", + "│ 3 │ /Users/cedric/.julia/v0.6/IJulia/src/execute_request.jl │\n", + "│ 4 │ task.jl │\n", + "│ 5 │ /Users/cedric/.julia/v0.6/Compat/src/Compat.jl │\n", + "│ 6 │ /Users/cedric/.julia/v0.6/IJulia/src/eventloop.jl │\n", "│ 7 │ /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl │\n", "│ 8 │ /Users/cedric/.julia/v0.6/Calculus/src/derivative.jl │\n", "│ 9 │ /Users/cedric/.julia/v0.6/Calculus/src/finite_difference.jl │\n", @@ -289,19 +270,19 @@ "\n", "│ Row │ function │ module │\n", "├─────┼────────────────────────────────────┼──────────────────────┤\n", - "│ 1 │ include_string │ Compat │\n", - "│ 2 │ IJulia.execute_request │ IJulia │\n", - "│ 3 │ include_string │ Base │\n", - "│ 4 │ IJulia.eventloop │ IJulia │\n", - "│ 5 │ FProfile.MissingInfo.missing_info │ FProfile.MissingInfo │\n", - "│ 6 │ IJulia.#14 │ IJulia │\n", + "│ 1 │ FProfile.MissingInfo.missing_info │ FProfile.MissingInfo │\n", + "│ 2 │ include_string │ Base │\n", + "│ 3 │ IJulia.execute_request │ IJulia │\n", + "│ 4 │ IJulia.#14 │ IJulia │\n", + "│ 5 │ include_string │ Compat │\n", + "│ 6 │ IJulia.eventloop │ IJulia │\n", "│ 7 │ Calculus.second_derivative │ Calculus │\n", "│ 8 │ Calculus.derivative │ Calculus │\n", "│ 9 │ Calculus.finite_difference_hessian │ Calculus │\n", "│ 10 │ Calculus.finite_difference │ Calculus │" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -319,22 +300,21 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - " 229 ...ulus/src/derivative.jl:71; second_derivative(::Function, ::F...\n", - " 227 .../finite_difference.jl:224; finite_difference_hessian(::Func...\n", - " 159 .../finite_difference.jl:55; finite_difference(::Calculus.##1...\n", - " 29 .../finite_difference.jl:27; finite_difference(::Calculus.##1...\n", - " 3 .../finite_difference.jl:54; finite_difference(::Calculus.##1...\n", - " 4 .../finite_difference.jl:0; finite_difference(::Calculus.##1...\n", - " 2 .../finite_difference.jl:0; finite_difference_hessian(::Func...\n" + " 180 ...ulus/src/derivative.jl:71; second_derivative(::Function, ::F...\n", + " 175 .../finite_difference.jl:224; finite_difference_hessian(::Func...\n", + " 112 .../finite_difference.jl:55; finite_difference(::Calculus.##1...\n", + " 20 .../finite_difference.jl:27; finite_difference(::Calculus.##1...\n", + " 3 .../finite_difference.jl:0; finite_difference(::Calculus.##1...\n", + " 5 .../finite_difference.jl:0; finite_difference_hessian(::Func...\n" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -358,6 +338,69 @@ "See `?flat` for more options." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Comparing results\n", + "\n", + "Pass two `ProfileData` objects to `flat` to compare them. The third column is simply the difference between the first two." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
count_pct_1count_pct_2count_pct_difffunction
119.5717.39-2.18Calculus.finite_difference_hessian
253.9154.420.51Calculus.derivative
314.6714.4-0.27Calculus.finite_difference
499.5799.590.02Calculus.second_derivative
599.8999.90.01IJulia.execute_request
699.8999.90.01include_string
799.8999.90.01IJulia.eventloop
899.8999.90.01IJulia.#14
999.8999.90.01FProfile.MissingInfo.missing_info
" + ], + "text/plain": [ + "9×4 DataFrames.DataFrame\n", + "│ Row │ count_pct_1 │ count_pct_2 │ count_pct_diff │\n", + "├─────┼─────────────┼─────────────┼────────────────┤\n", + "│ 1 │ 19.57 │ 17.39 │ -2.18 │\n", + "│ 2 │ 53.91 │ 54.42 │ 0.51 │\n", + "│ 3 │ 14.67 │ 14.4 │ -0.27 │\n", + "│ 4 │ 99.57 │ 99.59 │ 0.02 │\n", + "│ 5 │ 99.89 │ 99.9 │ 0.01 │\n", + "│ 6 │ 99.89 │ 99.9 │ 0.01 │\n", + "│ 7 │ 99.89 │ 99.9 │ 0.01 │\n", + "│ 8 │ 99.89 │ 99.9 │ 0.01 │\n", + "│ 9 │ 99.89 │ 99.9 │ 0.01 │\n", + "\n", + "│ Row │ function │\n", + "├─────┼────────────────────────────────────┤\n", + "│ 1 │ Calculus.finite_difference_hessian │\n", + "│ 2 │ Calculus.derivative │\n", + "│ 3 │ Calculus.finite_difference │\n", + "│ 4 │ Calculus.second_derivative │\n", + "│ 5 │ IJulia.execute_request │\n", + "│ 6 │ include_string │\n", + "│ 7 │ IJulia.eventloop │\n", + "│ 8 │ IJulia.#14 │\n", + "│ 9 │ FProfile.MissingInfo.missing_info │" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd2 = @fprofile 1000000 second_derivative(sin, 1.0)\n", + "flat(pd, pd2, combineby=:function)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Of course, this is most useful when comparing different algorithms or commits (see [Revise.jl](https://github.com/timholy/Revise.jl)). The differences in the above table are just noise." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -375,32 +418,32 @@ { "data": { "text/plain": [ - " 981 ./task.jl:335; (::IJulia.##14#17)()\n", - " 981 ...Julia/src/eventloop.jl:8; eventloop(::ZMQ.Socket)\n", - " 981 ...rc/execute_request.jl:154; execute_request(::ZMQ.Socket, ::...\n", - " 981 ...Compat/src/Compat.jl:464; include_string(::Module, ::Stri...\n", - " 981 ./loading.jl:515; include_string(::String, ::String)\n", - " 981 ./:?; FProfile.MissingInfo.missing_info\n", - " 981 ...ile/src/FProfile.jl:52; FProfile.MissingInfo.missing_info\n", - " 981 ./profile.jl:23; FProfile.MissingInfo.missing_info\n", - " 980 ...ile/src/FProfile.jl:67; FProfile.MissingInfo.missing_info\n", - " 977 .../src/derivative.jl:71; second_derivative(::Function...\n", - " 227 ...ite_difference.jl:224; finite_difference_hessian(:...\n", - " 159 ...ite_difference.jl:55; finite_difference(::Calculu...\n", - " 52 ...ite_difference.jl:55; finite_difference(::Base.#...\n", - " 41 ./math.jl:419; FProfile.MissingInfo.missi...\n", - " 22 ...ite_difference.jl:27; finite_difference(::Base.#...\n", - " 1 ...ite_difference.jl:0; finite_difference(::Base.#...\n", - " 1 ...ite_difference.jl:48; finite_difference(::Base.#...\n", + " 919 ./task.jl:335; (::IJulia.##14#17)()\n", + " 919 ...Julia/src/eventloop.jl:8; eventloop(::ZMQ.Socket)\n", + " 919 ...rc/execute_request.jl:154; execute_request(::ZMQ.Socket, ::...\n", + " 919 ...Compat/src/Compat.jl:464; include_string(::Module, ::Stri...\n", + " 919 ./loading.jl:515; include_string(::String, ::String)\n", + " 919 ./:?; FProfile.MissingInfo.missing_info\n", + " 919 ...ile/src/FProfile.jl:52; FProfile.MissingInfo.missing_info\n", + " 919 ./profile.jl:23; FProfile.MissingInfo.missing_info\n", + " 917 ...ile/src/FProfile.jl:67; FProfile.MissingInfo.missing_info\n", + " 913 .../src/derivative.jl:71; second_derivative(::Function...\n", + " 490 ...src/derivative.jl:3; derivative(::Function, ::Sy...\n", + " 175 ...ite_difference.jl:224; finite_difference_hessian(:...\n", + " 112 ...ite_difference.jl:55; finite_difference(::Calculu...\n", + " 2 ...ite_difference.jl:0; finite_difference(::Base.#...\n", + " 32 ...ite_difference.jl:27; finite_difference(::Base.#...\n", + " 64 ...ite_difference.jl:55; finite_difference(::Base.#...\n", + " 55 ./math.jl:419; FProfile.MissingInfo.missi...\n", + " 1 ./math.jl:300; FProfile.MissingInfo.missi...\n", " 1 ./math.jl:300; finite_difference(::Base.#...\n", + " 1 ...ite_difference.jl:48; finite_difference(::Base.#...\n", " 1 ...ite_difference.jl:54; finite_difference(::Base.#...\n", - " 29 ...ite_difference.jl:27; finite_difference(::Calculu...\n", - " 3 ...ite_difference.jl:54; finite_difference(::Calculu...\n", - " 4 ...ite_difference.jl:0; finite_difference(::Calculu...\n", - " 462 ...src/derivative.jl:3; derivative(::Function, ::Sy...\n", - " 12 ...src/derivative.jl:0; derivative(::Function, ::Sy...\n", - " 2 ...ite_difference.jl:0; finite_difference_hessian(:...\n", - " 1 .../src/derivative.jl:0; second_derivative(::Function...\n", + " 20 ...ite_difference.jl:27; finite_difference(::Calculu...\n", + " 3 ...ite_difference.jl:0; finite_difference(::Calculu...\n", + " 5 ...ite_difference.jl:0; finite_difference_hessian(:...\n", + " 5 ...src/derivative.jl:0; derivative(::Function, ::Sy...\n", + " 3 .../src/derivative.jl:0; second_derivative(::Function...\n", " 1 ...lus/src/derivative.jl:0; derivative(::Function, ::Symbol, ...\n" ] }, @@ -422,22 +465,22 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - " 981 IJulia\n", - " 981 Compat\n", - " 981 Base\n", - " 981 FProfile.MissingInfo\n", - " 978 Calculus\n", - " 41 FProfile.MissingInfo\n", + " 919 IJulia\n", + " 919 Compat\n", + " 919 Base\n", + " 919 FProfile.MissingInfo\n", + " 916 Calculus\n", + " 55 FProfile.MissingInfo\n", " 1 Calculus\n" ] }, - "execution_count": 18, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -450,7 +493,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If you're interested in a particular module/file/method/function, you can pass it to `tree`, along with an optional _neighborhood range_." + "If you're only interested in a particular module/file/method/function, you can pass it to `tree`, along with an optional _neighborhood range_." ] }, { @@ -461,13 +504,13 @@ { "data": { "text/plain": [ - " 978 ...rofile/src/FProfile.jl:67; FProfile.MissingInfo.missing_info\n", - " 977 ...lus/src/derivative.jl:71; second_derivative(::Function, ::F...\n", - " 227 .../finite_difference.jl:224; finite_difference_hessian(::Func...\n", - " 462 ...lus/src/derivative.jl:3; derivative(::Function, ::Symbol,...\n", - " 12 ...lus/src/derivative.jl:0; derivative(::Function, ::Symbol,...\n", - " 2 .../finite_difference.jl:0; finite_difference_hessian(::Func...\n", - " 1 ...lus/src/derivative.jl:0; second_derivative(::Function, ::F...\n" + " 916 ...rofile/src/FProfile.jl:67; FProfile.MissingInfo.missing_info\n", + " 913 ...lus/src/derivative.jl:71; second_derivative(::Function, ::F...\n", + " 490 ...lus/src/derivative.jl:3; derivative(::Function, ::Symbol,...\n", + " 175 .../finite_difference.jl:224; finite_difference_hessian(::Func...\n", + " 5 .../finite_difference.jl:0; finite_difference_hessian(::Func...\n", + " 5 ...lus/src/derivative.jl:0; derivative(::Function, ::Symbol,...\n", + " 3 ...lus/src/derivative.jl:0; second_derivative(::Function, ::F...\n" ] }, "execution_count": 10, @@ -494,11 +537,11 @@ { "data": { "text/plain": [ - "977 ...ulus/src/derivative.jl:71; second_derivative(::Function, ::Fl...\n", - " 227 .../finite_difference.jl:224; finite_difference_hessian(::Funct...\n", - " 462 ...lus/src/derivative.jl:3; derivative(::Function, ::Symbol, ...\n", - " 12 ...lus/src/derivative.jl:0; derivative(::Function, ::Symbol, ...\n", - " 2 .../finite_difference.jl:0; finite_difference_hessian(::Funct...\n" + "913 ...ulus/src/derivative.jl:71; second_derivative(::Function, ::Fl...\n", + " 490 ...lus/src/derivative.jl:3; derivative(::Function, ::Symbol, ...\n", + " 175 .../finite_difference.jl:224; finite_difference_hessian(::Funct...\n", + " 5 .../finite_difference.jl:0; finite_difference_hessian(::Funct...\n", + " 5 ...lus/src/derivative.jl:0; derivative(::Function, ::Symbol, ...\n" ] }, "execution_count": 11, @@ -518,7 +561,7 @@ "\n", "(if you want to build your own analysis)\n", "\n", - "The raw Profile data is available either through `Base.Profile.retrieve()`, or through `pd.data` and `pd.lidict`. However, you might find `FProfile.backtraces(::ProfileData)` more immediately useful. " + "The raw profiler data is available either through `Base.Profile.retrieve()`, or through `pd.data` and `pd.lidict`. However, you might find `FProfile.backtraces(::ProfileData)` more immediately useful. " ] }, { @@ -536,7 +579,7 @@ { "data": { "text/plain": [ - "10-element Array{StackFrame,1}:\n", + "11-element Array{StackFrame,1}:\n", " (::IJulia.##14#17)() at task.jl:335 \n", " eventloop(::ZMQ.Socket) at eventloop.jl:8 \n", " execute_request(::ZMQ.Socket, ::IJulia.Msg) at execute_request.jl:154\n", @@ -546,7 +589,8 @@ " macro expansion at FProfile.jl:52 [inlined] \n", " macro expansion at profile.jl:23 [inlined] \n", " macro expansion at FProfile.jl:67 [inlined] \n", - " second_derivative(::Function, ::Float64) at derivative.jl:71 " + " second_derivative(::Function, ::Float64) at derivative.jl:71 \n", + " derivative(::Function, ::Symbol, ::Symbol) at derivative.jl:3 " ] }, "execution_count": 12, diff --git a/README.md b/README.md index b1b1d02..1946c65 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,8 @@ [![codecov.io](http://codecov.io/github/cstjean/FProfile.jl/coverage.svg?branch=master)](http://codecov.io/github/cstjean/FProfile.jl?branch=master) -FProfile.jl is a nicer interface for Julia's [sampling -profiler](https://docs.julialang.org/en/latest/manual/profile/). It defines a few -profiling metrics not available in `Base.Profile`'s reports. +FProfile.jl provides more fully-featured reports for Julia's [sampling +profiler](https://docs.julialang.org/en/latest/manual/profile/). # Manual @@ -19,4 +18,4 @@ profiling metrics not available in `Base.Profile`'s reports. - [ProfileView.jl](https://github.com/timholy/ProfileView.jl) is a really good way to visualize profiling data. - [TraceCalls.jl](http://nbviewer.jupyter.org/github/cstjean/TraceCalls.jl/blob/master/README.ipynb#Profiling) can be useful to track down memory allocations and type-stability issues. - +- [StatProfiler.jl](https://github.com/tkluck/StatProfilerHTML.jl) \ No newline at end of file diff --git a/src/FProfile.jl b/src/FProfile.jl index 4b256dc..9cb3051 100644 --- a/src/FProfile.jl +++ b/src/FProfile.jl @@ -448,7 +448,7 @@ function flat(btraces::BackTraces; @assert !isempty(keys) "ProfileData contains no applicable traces" ntrace = sum(first, btraces) perc(var::Symbol, counts) = - (percent ? Symbol(var, "_percent") => round.(counts ./ ntrace * 100, 2) : + (percent ? Symbol(var, "_pct") => round.(counts ./ ntrace * 100, 2) : var => counts) count_cols = [perc(:count, [count_dict[sf] for sf in keys])] if _module !== nothing @@ -461,12 +461,11 @@ function flat(btraces::BackTraces; if is_applicable(f, first(keys))]...)) if _module !== nothing; df = df[[m in _module for m in df[:module]], :] end if !inlined; df = df[!is_inlined.(df[:stackframe]), :] end - return sort(df, cols=percent ? :count_percent : :count, rev=true) + return sort(df, cols=percent ? :count_pct : :count, rev=true) end flat(pd::ProfileData, _module::Tuple; kwargs...) = flat(pd; kwargs..., _module=_module) - flat(pd::ProfileData, _module::Module; kwargs...) = flat(pd; kwargs..., _module=(_module,)) @@ -477,4 +476,42 @@ df_combineby(df::DataFrame) = tree(pd::ProfileData, df::DataFrame, nrow::Int, neighborhood::UnitRange=-1:1) = tree(pd, df[nrow, df_combineby(df)], neighborhood) +################################################################################ +# Comparisons + +function my_outer_join(df1, df2, on::Vector) + # See DataFrames.jl#1270 for why this is necessary + kept = setdiff(names(df1), on) + row_vals(df, i) = map(last, DataFrameRow(df, i)) + mk_dict(df) = Dict(row_vals(df, i)=>i for i in 1:size(df, 1)) + dict1 = mk_dict(df1[:, on]) + dict2 = mk_dict(df2[:, on]) + df_keys = unique(vcat(df1, df2)[on]) + build_col(df, dict, col) = [haskey(dict, row_vals(df_keys, i)) ? + df[dict[row_vals(df_keys, i)], col] : 0 + for i in 1:size(df_keys, 1)] + df_kept = DataFrame() + for col in kept + col1, col2 = Symbol(col, :_1), Symbol(col, :_2) + df_kept[col1] = build_col(df1, dict1, col) + df_kept[col2] = build_col(df2, dict2, col) + df_kept[Symbol(col, :_diff)] = round.(df_kept[col2] .- df_kept[col1], 2) + end + return hcat(df_kept, df_keys) +end + + +function flat(pd1::ProfileData, pd2::ProfileData; _module=nothing, kwargs...) + df1 = flat(pd1; _module=_module, kwargs...) + df2 = flat(pd2; _module=_module, kwargs...) + combineby_ind = _module === nothing ? 2 : 3 + df = FProfile.my_outer_join(df1, df2, names(df1)[combineby_ind:end]) + return sort(df, cols=names(df)[3], by=abs, rev=true)::Any +end + +flat(pd1::ProfileData, pd2::ProfileData, _module::Tuple; kwargs...) = + flat(pd1, pd2; kwargs..., _module=_module) +flat(pd1::ProfileData, pd2::ProfileData, _module::Module; kwargs...) = + flat(pd1, pd2; kwargs..., _module=(_module,)) + end # module