Thanks for the feedback. I'm not trying to be awkward here, just trying to get my head around everything.
Oh, and I completely agree with the risks of premature optimisation. Thanks, Stuart On Mar 10, 5:03 pm, David Pollak <feeder.of.the.be...@gmail.com> wrote: > On Wed, Mar 10, 2010 at 7:22 AM, Stuart Roebuck > <stuart.roeb...@gmail.com>wrote: > > > Okay, so I now understand what is happening a little better. > > > When I saw a construct like: > > > bind("example",xhtml, > > "first_name" -> SHtml.text(user.first_name, user.first_name(_)), > > "last_name" -> SHtml.text(user.last_name, user.last_name(_)) > > > it reminded me of a match with cases and my assumption was that each > > match would only be called if and when the match was found. In reality > > what appears to happen is that the item on the right hand side of the > > "->" is usually evaluated and then placed into a Map with the String > > like "first_name" being the key. > > You're welcome to take up laziness vs. strictness with the EPFL team. > There's only so much we can do to be lazy and it does take extra syntax > (see Ross's reply). > > > So, if every binding is used in every case there is no big issue here, > > but if you have bindings that aren't all used they will none-the-less > > be evaluated every time you try to bind. > > > Also every time the bind function is called a new Map appears to be > > generated and indexed in memory which doesn't seem as efficient as it > > could be. > > There's a sign over a urinal in a mens room at Google that reads "Premature > Optimization is the root of all evil." Now, I think that's an > overstatement, but in this case, it's applicable. > > Is there an *actual* problem with building a Map()? Can you measure the > problem? Do you have a more efficient solution? > > Now, when I wrote that particular code, I was very cognizant of the > performance implications. > > The cost of producing the Map() (backed by a HashMap) in the normal case (no > hash collisions) is O(n). Worst case is O(n log n). > > For each element we're binding, we have look up the tag of the node to bind. > If we are using our Map(), the look-up time is O(1) (or worst case O(log > n)). If we have n elements that we're binding, the expected cost is O(n) > and worst case is O(n log n). > > So, we have an algorithm that normally executes in 2xO(n) and worst case > 2xO(n log n). > > Now, if we didn't create the Map, we'd have to cycle through the possible > binds and we'd wind up with O(n ^ 2). Even if you have a PartialFunction > (pattern matching) against strings, it's O(n) to match the pattern. > > So, would you rather have an O(n) algorithm that can degrade to O(n log n) > and uses marginally more memory or would you rather have an O(n ^ 2) > algorithm that uses marginally less memory? > > And if you're worried about the memory used by the Map(), on pre 1.6 build > 16 JVMs, the Map will not likely escape the Eden memory pool (which means > very quick GC). On the most recent JVMs, the escape analysis should kick in > and the Map and its elements will be allocated on the heap and never be > subject to GC. > > > > > I can't help but wonder whether this could be converted to a form of > > match which would then be built at compile time and re-used and would > > only evaluate those matches that matched. > > In the event that you can create a benchmark and a real-world situation that > actually needs this, please open a ticket. But, I suspect that even if you > pre-created a Map and passed it into bind(), that the performance would be > nearly identical, but we'd have more public APIs to document which seems to > be something that also annoys you. > > > > > > > > > In the meantime I see that you can convert the code above to: > > > bind("example",xhtml, > > FuncBindParam("first_name", () => SHtml.text(user.first_name, > > user.first_name(_)), > > FuncBindParam("last_name", () => SHtml.text(user.last_name, > > user.last_name(_)) > > > to get a form of lazy evaluation. > > > On Mar 10, 11:01 am, Stuart Roebuck <stuart.roeb...@gmail.com> wrote: > > > I've been trying to figure why some binding is giving me a stack > > > overflow and I've discovered that if you use the BindHelpers.bind > > > method with a set of function BindParams, all the functions are > > > evaluated regardless of whether a match is found. > > > > So, for example, if you bind to an empty NodeSeq and have a BindParam > > > which will never match like: > > > "you won't find me here" -> { print("Got here!"); > > > NodeSeq.Empty } > > > …you find that the print statement is called. > > > > This really surprised me. Is this intentional behaviour as it seems > > > to be a potential source of significant redundant processing? > > > > Stuart. > > > -- > > You received this message because you are subscribed to the Google Groups > > "Lift" group. > > To post to this group, send email to lift...@googlegroups.com. > > To unsubscribe from this group, send email to > > liftweb+unsubscr...@googlegroups.com<liftweb%2bunsubscr...@googlegroups.com > > > > > . > > For more options, visit this group at > >http://groups.google.com/group/liftweb?hl=en. > > -- > Lift, the simply functional web frameworkhttp://liftweb.net > Beginning Scalahttp://www.apress.com/book/view/1430219890 > Follow me:http://twitter.com/dpp > Surf the harmonics -- You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to lift...@googlegroups.com. To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.