On Jun 20, 3:44 pm, eliben <[EMAIL PROTECTED]> wrote: > On Jun 20, 3:19 pm, George Sakkis <[EMAIL PROTECTED]> wrote: > > > > > On Jun 20, 8:03 am, eliben <[EMAIL PROTECTED]> wrote: > > > > On Jun 20, 9:17 am, Bruno Desthuilliers <bruno. > > > > [EMAIL PROTECTED]> wrote: > > > > eliben a écrit :> Hello, > > > > > > In a Python program I'm writing I need to dynamically generate > > > > > functions[*] > > > > > (snip) > > > > > > [*] I know that each time a code generation question comes up people > > > > > suggest that there's a better way to achieve this, without using exec, > > > > > eval, etc. > > > > > Just to make things clear: you do know that you can dynamically build > > > > functions without exec, do you ? > > > > Yes, but the other options for doing so are significantly less > > > flexible than exec. > > > > > > But in my case, for reasons too long to fully lay out, I > > > > > really need to generate non-trivial functions with a lot of hard-coded > > > > > actions for performance. > > > > > Just out of curiousity : could you tell a bit more about your use case > > > > and what makes a simple closure not an option ? > > > > Okay. > > > > I work in the field of embedded programming, and one of the main uses > > > I have for Python (and previously Perl) is writing GUIs for > > > controlling embedded systems. The communication protocols are usually > > > ad-hoc messages (headear, footer, data, crc) built on top of serial > > > communication (RS232). > > > > The packets that arrive have a known format. For example (YAMLish > > > syntax): > > > > packet_length: 10 > > > fields: > > > - name: header > > > offset: 0 > > > length: 1 > > > - name: time_tag > > > offset: 1 > > > length: 1 > > > transform: val * 2048 > > > units: ms > > > - name: counter > > > offset: 2 > > > length: 4 > > > bytes-msb-first: true > > > - name: bitmask > > > offset: 6 > > > length: 1 > > > bit_from: 0 > > > bit_to: 5 > > > ... > > > > This is a partial capability display. Fields have defined offsets and > > > lengths, can be only several bits long, can have defined > > > transformations and units for convenient display. > > > > I have a program that should receive such packets from the serial port > > > and display their contents in tabular form. I want the user to be able > > > to specify the format of his packets in a file similar to above. > > > > Now, in previous versions of this code, written in Perl, I found out > > > that the procedure of extracting field values from packets is very > > > inefficient. I've rewritten it using a dynamically generated procedure > > > for each field, that does hard coded access to its data. For example: > > > > def get_counter(packet): > > > data = packet[2:6] > > > data.reverse() > > > return data > > > > This gave me a huge speedup, because each field now had its specific > > > function sitting in a dict that quickly extracted the field's data > > > from a given packet. > > > It's still not clear why the generic version is so slower, unless you > > extract only a few selected fields, not all of them. Can you post a > > sample of how you used to write it without exec to clarify where the > > inefficiency comes from ? > > > George > > The generic version has to make a lot of decisions at runtime, based > on the format specification. > Extract the offset from the spec, extract the length. Is it msb- > first ? Then reverse. Are specific bits required ? If so, do bit > operations. Should bits be reversed ? etc.
So you are saying that for example "if do_reverse: data.reverse()" is *much* slower than "data.reverse()" ? I would expect that checking the truthness of a boolean would be negligible compared to the reverse itself. Did you try converting all checks to identity comparisons with None ? I mean replacing every "if compile_time_condition:" in a loop with compile_time_condition = compile_time_condition or None for i in some_loop: if compile_time_condition is None: ... It's hard to believe that the overhead of identity checks is comparable (let alone much higher) to the body of the loop for anything more complex than "pass". George -- http://mail.python.org/mailman/listinfo/python-list