Syntax example

Hi Chris,

I found today an issue I couldn’t easily solve within MWorks.

I have a bunch of lists: varAList, varBList,varCList,varDList
and a variable I use as an index: N.

I’d like to do two things from the XML/MWEL:

  1. index the list with the variable, or if the list is length 1, use the first element.
    Python example:
    if len(varList) == 1:
    var = varList[0]
    else
    var = varList[N]
    What I currently do is something like: (python)
    def assign_list_or_one(varListStr, indexStr, varStr):
    vL = mw.getvar(varListStr)
    if len(vL) == 1:
    out = vL[0]
    else:
    out = vL[mw.getvar(indexStr)]
    mw.setvar(varListStr, out)
    (xml)
    <action=“run_python_string” code=“assign_list_or_one(‘varList’, ‘N’, ‘var’)”/>
  2. check to make sure all lists are the same length, or length 1
    There’s not really an easy way to do this without temp vars in XML/MWEL.

First, do you see an easier way to do (1), perhaps within the XML/MWEL, without making the code too unreadable?

If I do 10-20 of the calls into python in (1), do you think that will be a speed issue? (i.e. do you have a sense of how much overhead time run_python_string takes to call into and out of python, and how much time mw.getvar() / setvar() take for scalars or reasonable-sized lists?)

And this is the kind of thing that would be easier if there was a Python MW experiment language. But perhaps the current run_python_string solution is the best compromise.

Mark

Hi Mark,

First, do you see an easier way to do (1), perhaps within the XML/MWEL, without making the code too unreadable?

How about this?

varList[[0, index][size(varList) > 1]]

That expression will work in XML or MWEL. In MWEL, you could create a macro for it:

%define first_or_nth(list, index) list[[0, index][size(list) > 1]]

If I do 10-20 of the calls into python in (1), do you think that will be a speed issue? (i.e. do you have a sense of how much overhead time run_python_string takes to call into and out of python, and how much time mw.getvar() / setvar() take for scalars or reasonable-sized lists?)

I didn’t know, so I wrote a simple timing test (attached). The test computes the elapsed time per assignment, averaged over 1000 assignments, for lists of length 1, 10, 100, 1000, and 10000.

Without Python, using the first_or_nth macro defined above, I get the following results on my Mac Pro:

Average elapsed time per assignment:
          1-item list:   30.774 us
         10-item list:   33.078 us
        100-item list:   35.654 us
       1000-item list:   53.526 us
      10000-item list:   204.227 us

With Python, using the equivalent of your assign_list_or_one function, I get the following:

Average elapsed time per assignment:
          1-item list:   62.106 us
         10-item list:   64.307 us
        100-item list:   74.065 us
       1000-item list:   166.576 us
      10000-item list:   1180.75 us

For lists with 100 items or fewer, the Python version takes about twice as long. With 1000 and 10000 items, the Python version takes about 3 and 6 times longer, respectively. The multiplier gets larger with larger lists, because the entire MWorks list is converted into a Python list by getvar.

And this is the kind of thing that would be easier if there was a Python MW experiment language.

I think I’ve made the case that (1) isn’t any harder without Python. What is the “easy” way to do (2)?

Chris

Attachment: run_python_timing.zip (1.73 KB)