How to measure and capture a script’s execution time in DolphinDB? - time

I’d like to measure and capture my script’s execution time and assign it to an variable. I tried to assign the return of function timer to variable a, but it raised an exception of “invalid expression”.
a = timer x=1

The exception is raised because timer is not a function but a procedure. It only prints a message that cannot be assigned to a variable. However, you can use function evalTimer, which returns a scalar that can be assigned to a variable.
To use function evalTimer, you can rewrite the statement block as a user-defined function. See evalTimer — DolphinDB 1.3 documentation
You can also check the syntax of a function with syntax:
syntax(evalTimer)
// evalTimer(funcs, [count=1])
funcs: the function(s) for which the execution time is measured
count: the number of times funcs will be executed. The default value is 1.
To measure the execution time of function foo:
def foo(){
x=1
}
a= evalTimer(foo,10);
print(a)
// output: 0.031341
In the above example, the code to be executed is encapsulated into a user-defined function foo. Then use function evalTimer to measure the time of running function foo 10 times, assign the result to variable a, and print it out.

Related

Confusing julia behavior. #everywhere macro changes the scope of local variables to global

I just encountered a very confusing julia behavior. I always thought that variables defined inside a function remain local to that function. But in the following example, the scope changes.
I define a simple function as below
using Distributed
addprocs(2)
function f()
#everywhere x = myid()
#everywhere println("x = ", x)
end
Executing the following code
f()
gives the result
x = 1
From worker 2: x = 2
From worker 3: x = 3
But since x is defined inside the function, I would expect the variable x to be not defined outside the function. However, upon executing the following code
x
I get the result
1
Even more confusing is the execution of the following code
#fetchfrom 3 x
which again gives
1
This is super confusing behavior. First, how does x become available outside the function? Second, why are all the processors/cores returning the same value of x? Thank you for your help.

Is the call stack and execution context used when calling functions using the return value of other functions as arguments?

I learnt about how call stacks and execution contexts are used in recursive functions. Just curious if the same method is used when we call functions using the return value of other functions as arguments?
No, that would not be the same. Where with recursive calls a function context remains on the stack while the recursive call is made, this is not the case when you make function calls of which the return arguments are used in a subsequent call.
So for instance, if we have three functions f, g and h, and this code:
result = f(g(1), h(2))
...then there is not much difference (with respect to the call stack) with this code:
result1 = g(1)
result2 = h(2)
result = f(result1, result2)
The only difference is that the function results are also stored in variables result1 and result2. But the main point here is that the call to h is not made before the call of g has returned, and the call to f is not made before h has returned: there is no situation where one of these function execution contexts is on the stack while a deeper call is made.

$RANDOM being constant when returning it from a function

getRandom () {
echo $RANDOM
}
getRandomFromGetRandom () {
echo $(getRandom)
}
Calling getRandom does the expected every time, it returns some random number on each call.
What I'd expect is the same from getRandomFromGetRandom, that a random number being called every time I call getRandomFromGetRandom, but that's not the case. Every time that function is called it returns a constant which changes only when I open another instance of the terminal.
man zshparam says:
The values of RANDOM form an intentionally-repeatable pseudo-random sequence; subshells that reference RANDOM will result in identical pseudo-random values unless the value of RANDOM is referenced or seeded in the parent shell in between subshell invocations.
Since command substitution is performed in a subshell, this explains the repetitive values getRandomFromGetRandom prints. To fix it, reference RANDOM before echoing $(getRandom), like
getRandomFromGetRandom () {
: $RANDOM
echo $(getRandom)
}
Or seed it (zsh-only; won't work on yash)
getRandomFromGetRandom () {
RANDOM= echo $(getRandom)
}
(Almost) All Random implementations are based on saved state. Calculating the value of the next random number depends only on the state, and will modify the state so that the next call will yield different number. When a process is forked, the state of the parent is copied into the state of the children.
In the posted code, the getRandom is calculated in a sub-shell (because of $(getRandom)). As a result, the code repeated uses the inherit state from the parent, which is never updated. The next call therefore will use the same (parent) state, and will result in the same number.
The first two iterations will look like:
Iteration 1:
Parent initialize parent_state to S0
Parent fork, child_state set to S0 (copied from parent_state)
Child calculate first random using S0, result is R0, modified child_state = S1
Child exit, returns R1 to parent (via stdout, print with echo)
Iteration 2:
Parent fork agin, child set set to S0 (copied from parent_state)
Child calculate second random using S0, result is R0, modified child_state = S1
Child exit, returns R1 to parent (via stdout, print with echo)
The following shows how to get similar logic to work
getRandom () {
my_random=$RANDOM
}
getRandomFromGetRandom () {
getRandom
echo "$my_random"
}
getRandomFromGetRandom
getRandomFromGetRandom

What gets executed first in a nested function?

When I create a constant to put my closure to work:
let incrementByTen = makeIncrementer(forIncrement: 10)
Does it skip incrementer() until it's called in the return statement, that way the return statement can run the incrementer() function in the end and receive its value?
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
The arguments to a function are evaluated when the function is called. In this case that means that when makeIncrementer is called, it's argument (10 in this case) will be evaluated before makeIncrementer is actually called.
Likewise, when makeIncrementer is invoked, it's code will be executed in sequence, initializing runningTotal and then initializing incrementer (note that at this point amount has been evaluated already, so in the returned incremented, it is ALWAYS 10.
Subsequently, when you invoke incrementByTen() there are no arguments to pass and nothing to be evaluated before the call, as part of executing the closure, runningTotal will be incremented by amount, in this case, always 10.
In a comment you have extended your question with:
I've read that this function captures a reference to runningTotal and amount. What's hard to grasp is how it keeps increasing when I repeatedly call incrementByTen().
The function incrementer captures the value of amount and the variable runningTotal. Capturing a value just involves copying the value into the function value (aka closure).
Capturing the variable is more involved: as a local variable runningTotal's lifetime would usually only extend at most to the end of the function invocation it is created by - so a call to makeIncrementer would create a new local runningTotal and when that call returned the variable would be destroyed. However as runningTotal is captured as a variable by incrementer then its lifetime is automatically extended as long as it is required by incrementer, which is as long as incrementer itself is required. As incrementer is the value returned by makeIncrementer the lifetime of runningTotal extends past the lifetime of the call to makeIncrementer.
Later each time the function returned by a single call to makeIncrementer is invoked as it has captured the variable runningTotal from that call it is incremented by 10 and its current value returned.
If you call makeIncrementer twice and store both results, then each result references a distinct function and each of those functions references a distinct variable - so you have two distinct incrementing counters.
HTH

Result of boost::posix_time::milliseconds(0)

What is the behaviour of boost::posix_time::milliseconds() function if value 0 is passed as argument to this function?
The function boost::posix_time::milliseconds(long) creates an object of type time_duration which represents a certain amount of time. boost::posix_time::milliseconds(0) will, therefore, represent a duration of 0 seconds.

Resources