1
$\begingroup$

Will it be slower to place functions' defintions inside a main function?
I usually do that if the subfunctions are short.
However, with a long subfunction I usually place it outside as I think that would make it easier to read and run faster.
Now I want to do it as the first method below as I want to make it self-contained and easier to manage when I do copy-paste and re-use.
If I place them outside, I usually miscopy some functions and make it not running properly. But I'm worrying if it's slower and harder to read.

I understand about the local/global effect but I want to focus on the speed and readability here.

Method 1: Place function1 and function2 inside the main function.

   myFunction[parameters_] := Module[{},
  
  function1[parameters1_] := Module[{},
    (* a long function*)
    do something here
    ];
  function2[parameters2_] := Module[{},
    (* a short function*)
    do something here
    ];
  
  (*use function1 and function2 to do something more*)
  
  ]

Method 2:

  function1[parameters1_] := Module[{},
    (* a long function*)
    do something here
    ];

  function2[parameters2_] := Module[{},
    (* a short function*)
    do something here
    ];

myFunction[parameters_] := Module[{},
  
  (*use function1 and function2 to do something more*)
  
  ]
$\endgroup$
6
  • $\begingroup$ Whenever someone asks a question about the execution speed of A v B I ask What did your measurements tell you already? $\endgroup$ Feb 7 at 15:20
  • $\begingroup$ @HighPerformanceMark not much difference for my current case but I can imagine that I may put 10 functions' definitions inside a function and not quire sure what would it be. $\endgroup$
    – internet
    Feb 7 at 15:31
  • $\begingroup$ Is there an intent of these functions to be visible outside myFunction, or to specifically not be visible? With the above construct they're definitely visible outside. $\endgroup$
    – kirma
    Feb 7 at 15:33
  • $\begingroup$ @kirma I don't have intention to use them outside. In the first method I place function1 and function2 inside another function so I believe they're local only. Am I wrong? $\endgroup$
    – internet
    Feb 7 at 15:40
  • 1
    $\begingroup$ @kirma you're right. I forgot about that. As for adding Module which contains both helper functions and the main function, could you add it as answer or any reference? $\endgroup$
    – internet
    Feb 7 at 15:55

2 Answers 2

2
$\begingroup$

Given that you told on the comments that you want the internal functions not to be visible probably the best method is the following:

Define all functions, internal and main, inside a Module. Put those functions which you don't want to be publicly visible on the Module symbols list; the rest will become publicly visible. There shouldn't be performance issues; all definitions are evaluated only once.

Module[
 {function1, function2},

 function1[parameters1_] := 
  (Echo["function1 was here"]; parameters1);

 function2[parameters2_] := 
  (Echo["function2 was here"]; parameters2);

 myFunction[parameters_] :=
  (function1[parameters]; 
   function2[parameters]);
 ]

Now the main function is visible and can call internal functions:

myFunction[42]

(* function1 was here *)

(* function2 was here *)

(* 42 *)

At the same time, internal functions are not publicly visible:

function1[42]

(* function1[42] *)

function2[42]

(* function2[42] *)
$\endgroup$
1
  • $\begingroup$ I see. I think this is what I'm looking for. If I copy it somewhere then I just need to copy the whole module. $\endgroup$
    – internet
    Feb 7 at 16:08
2
$\begingroup$

There is not a big difference, but for housekeeping the first method is to be preferred:

myFunction[] := Module[{},
   function1[] := Module[{},
     Sqrt /@ Range[10^4]];
   function2[] := Module[{},
     Sqrt /@ Range[10^4];];
   function1[];
   function2[]];
myFunction[] // RepeatedTiming

(* {0.135302, Null} *)


function1[] := Module[{}, Sqrt /@ Range[10^4];];
function2[] := Module[{}, Sqrt /@ Range[10^4];];
myFunction[] := Module[{}, function1[]; function2[]]
myFunction[] // RepeatedTiming

(* {0.114168, Null} *)
$\endgroup$
2
  • $\begingroup$ Thanks, do you usually write it as the first method? $\endgroup$
    – internet
    Feb 7 at 15:33
  • 1
    $\begingroup$ If function1 is only used inside another one and it is simple and not hard to debug, I usually include it in the outer function. $\endgroup$ Feb 7 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.