The Source for Java Technology Collaboration
User: Password:



Shannon Hickey

Shannon Hickey's Blog

Beans Binding 1.1.1 Beats 1.0's Butt, Bigtime

Posted by shan_man on October 19, 2007 at 01:08 PM | Comments (15)

I'm pleased to announced that version 1.1.1 of Beans Binding has just been released at http://beansbinding.dev.java.net/. This release provides a drastic increase in performance over 1.0, the addition of support for binding to a JSpinner's value property, and a small set of bug fixes.

Extreme performance gains in this release are the result of a fix made to the BeanProperty and ELProperty classes. As these classes are central to Beans Binding, most things now perform many orders of magnitude faster. Consider the following simple test case, that fetches the value of a property 100,000 times for the same object:


    Person person = new Person("John", "Smith");
    Property p = BeanProperty.create("firstName");
    p.addPropertyStateListener(person, new PSL());

    long start = System.currentTimeMillis();

    for (int i = 0; i < 100000; i++) {
        p.getValue(person);
    }

    System.out.println(System.currentTimeMillis() - start);

In 1.0, this test takes approximately 13,000 milliseconds on my machine. On the contrary, it takes approximately 8 milliseconds in 1.1.1. How's that for bigtime?! You can imagine how applications with many bindings, or components like JTable and JList with large data sets, will perform much better with this version.

I imagine some of you are curious as to how this incredible change in performance was possible. As described in the JavaDoc for BeanProperty and ELProperty, once a listener is installed on the property, values along the paths are cached, and only updated in respose to property change notifications. Knowing that developers are likely to encounter beans that don't fire the correct notifications, and that resulting problems may pose tricky to debug, I began work on allowing developers to turn on a debug option that would have BeanProperty and ELProperty log a message when they detect such a change without notification. They would do this by re-evaluating the entire path on every method call and comparing each object to what they have in their cache. This would, of course, remove any performance gains accomplished by the caching; but only when the debug option is on.

While the toggle for this debug option hasn't yet been added, it turns out that in 1.0 the logic itself was left turned on, only without the messaging—a code path that served only to remove all caching benefits. In 1.1.1 this code path has been turned off pending completion of the debugging feature.

And since we're talking about performance, I'd like to share something else with those of you looking to get every last drop of speed from the current implementation. Naturally you'd expect BeanProperty to perform better than ELProperty for simple paths, since the former avoids the overhead of EL parsing. This will, of course, be true once the implementation has been further optimized. In the current release, however, ELProperty actually performs better in many cases. Consider the following test case that creates a new BeanProperty 100,000 times, and uses each instance to fetch the value for a new object:


    long start = System.currentTimeMillis();

    for (int i = 0; i < 100000; i++) {
    	Property p = BeanProperty.create("firstName");
        p.getValue(new Person("John", "Smith"));
    }

    System.out.println(System.currentTimeMillis() - start);

This test dramatizes the case of an application that creates and binds a large set of bindings, with similar properties, perhaps on the first initializion of a GUI form. In 1.1.1, this code takes approximately 7000 milliseconds on my machine. But replacing BeanProperty with ELProperty reduces it to 330 milliseconds.

Consider this similar test case that uses a single BeanProperty and fetches its value for 100,000 new objects:


    long start = System.currentTimeMillis();
    
    Property p = BeanProperty.create("firstName");
    
    for (int i = 0; i < 100000; i++) {
        p.getValue(new Person("John", "Smith"));
    }
    
    System.out.println(System.currentTimeMillis() - start);

This test dramatizes what JTable or JList might have to do while scrolling, to fetch the value of a single property for a large set of objects. In 1.1.1, this test takes approximately 6900 milliseconds on my machine. Replacing BeanProperty with ELProperty reduces it to 260 milliseconds.

I raise this discussion as a point of interest, not to encourage you to switch to ELProperty (unless your application demands the performance increase that it currently brings). As I mentioned, BeanProperty will be optimized to be the better choice for simple paths. Profiling indicates that the source of ELProperty's higher performance lies with EL's built-in caching of JavaBean BeanInfos—something that can easily be added to BeanProperty.

One final note before I sign off for the weekend: Some of you might ask why the release number has jumped from 1.0 to 1.1.1. The answer is that I actually first released a 1.1, and before I had finished writing up an announcement, internal testing revealed an existing, but previously unknown bug that I thought was worth fixing quickly. Hence 1.1.1. Enjoy!


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Shannon,

    That sounds very good. Thank you for the continued great work.

    Can you tell me if this version addresses the JComboBox issue I raised on the mailing list a while back?

    Last time I tried I was not able to make the JComboBox work as it does in the 0.6.1 version we're using now.

    TIA,
    Carl

    Posted by: carljmosca on October 19, 2007 at 02:49 PM

  • perfect. Thank you for listening to the community - I will update the NetBeans OpenGL Pack ASAP.

    Posted by: mbien on October 21, 2007 at 10:01 AM

  • Hi carljmosca: After many days of work trying to solve issues with JComboBoxBinding.DetailBinding, and trying to implement a "selectedElement" property for JComboBox, I had to temporarily abandon these things in order to release 1.0 on schedule. As such, the current JComboBoxBinding is quite simple and, likewise, only a simple "selectedItem" property has been exposed for JComboBox. Current plans include returning to the component for a future release. As for other questions regarding JComboBox binding, I'll continue to work with you on the users mailing list to help diagnose issues and answer questions. Thanks!

    Posted by: shan_man on November 01, 2007 at 09:58 AM

  • mbien: Thanks for your feedback! And thank you for bringing to my attention the (now resolved) performance issue with JTable sorting!

    Posted by: shan_man on November 01, 2007 at 09:59 AM

  • Using 1.1.1 and

    Property uiProperty = ELProperty.create("${"+"value"+"}");
    Property modelProperty = ELProperty.create("${"+modelPropertyName+"}");
    Binding binding =
    Bindings.createAutoBinding(updateStrategy,
    model,
    modelProperty,
    ui,
    uiProperty);
    binding.bind();

    It usually takes around 15ms to call binding.bind().
    With BeanProperty.create instead of ELProperty.create it took 3x as long.

    This is for binding a JFormattedTextField to a field in a POJO.

    With 30-40 JFormattedFields it takes longer to bind the data to the gui than it takes to get the data from the database on another machine...

    Reducing the time bind() takes would be reallly helpful.

    Otherwise, great stuff :)

    Posted by: blackbrrd on November 07, 2007 at 04:30 AM

  • Hello Shannon, nice work! the new beansbinding is really easier to use. Thanks for your work!
    I have a small problem: the method BeanProperty.create(path) returns an object of type BeanProperty<Object, Object>, but the method SwingBindings.createJTableBinding(AutoBinding.UpdateStrategy strategy, SS sourceObject, Property<SS, List<E>>, sourceListProperty, JTable targetJTable) needs an object of type Property<Object, List<Object>>.

    My question ist: how can I create such a property object using the BeanProperty.create() method?

    The code is like:

    SwingBindings.createJTableBinding(READ, source, BeanProperty.create(listPropertyName), table, null);

    Thanks.

    Posted by: polygoncell on November 07, 2007 at 05:32 AM

  • Hi, Shannon, I got the solution. It should be

    BeanProperty.<Object, List<Object>>create(listPropertyName)

    Posted by: polygoncell on November 07, 2007 at 05:42 AM

  • Hi polygoncell: Thanks for the nice feedback! As to your question, it looks like you've solved it yourself. And great on you for doing so - I actually learned that particular generics syntax myself while working on this project, and it's been quite handy!

    Posted by: shan_man on November 13, 2007 at 01:51 PM

  • Hi, Shannon, nice to get your answer. I appreciate it. Yes, generic is amazing :-))

    I get another question: with the beansbinding 0.6 I can bind two Colletions like this:


    public class Model1 extends AbstractBean {

    private Bean1 bean1;

    // init bean1
    // setter & getter
    }

    public class Bean1 extends AbstractBean {
    private List children = ObservableCollections
    .observableList(new ArrayList());

    // setter & getter
    }

    public class Controller {

    private List list = ObservableCollections
    .observableList(new ArrayList());

    // setter & getter
    }

    Controller controller = new Controller();
    Model1 model1 = new Model1();

    getBindingContext().addBinding(model1, ${bean1.children}, controller, "list");
    ....

    with this example, the "children" collection of bean1, which is hold by model1 is bound with the "list" collection of the controller. I can add, modify, and delete some elements of one collection and the other collection will be updated by the beansbinding.

    now, I have updated the beansbinding from 0.6 to 1.2 and want to keep the collections being bound. I do it like this:

    Bindings.createAutoBinding(
    READ_WRITE,
    model1, BeanProperty.create("bean1.children"),
    controller,
    BeanProperty.create("list")).bind();


    Unfortunately, it does not work 100% correctly. It works great when bean1of the model1 is loaded(the "list" collection is, at this time, synchronized with the "children" collection of bean1). It works great when the element of one collection is modified. But it does not work when I add element into & delete element from one collection.

    Is there anything that I have done in a wrong way? Thanks for your answer.

    Posted by: polygoncell on November 14, 2007 at 02:40 AM

  • I am trying to bind a property of my bean named "iReportPath". I have methods:
    getIReportPath()
    setIReportPath()

    Beans Binding 1.2.1 silently does no binding in this case (it should throw an exception when binding does not work).

    To make it work, I have to rename my property to "ireportPath" and use these method names:
    getIreportPath()
    setIreportPath()

    Is this a bug?

    Posted by: boerkel on December 20, 2007 at 01:20 AM

  • Apparently, java.beans.Introspector.decapitalize() converts the "IReportPath" part of "getIReportPath()" to "IReportPath" and if I name my property like this, binding works!

    Posted by: boerkel on December 20, 2007 at 03:00 AM

  • You wrote like 5 months ago "It is my hope that the JavaDoc provided with this release will have you well on your way to binding with the new API very quickly. While I would love to take you on a tour through the entire API here, composing such a tutorial would delay this announcement. As such, I'll present a few examples to get you started, let you get going with the new API, and then follow up with additional blog entries, as time allows, on particulars deserving more attention. As always, please feel free to send me your questions and/or feedback at any time. "

    My questionx are :

    There is no new blog entry , there is no tutorial so what is going with this project ?

    What is the status of this project ?

    Thx.

    Posted by: csergiu77 on January 31, 2008 at 02:29 PM

  • Hello Shannon,

    I am trying to learn more about EL and beansbinding but I am missing the connection between some old code snippets and the current version. How could I get the following code (from your JavaOne 2007 presentation) working with version 1.2.1??

    Binding binding = new Binding(
    bugTable,
    “${bb:listSize(selectedElements)} of” +
    “${bb:listSize(elements)} are selected”
    summaryLabel,
    "text");

    I really appreciate your help - actually, anyone's help :)
    Thanks!

    Posted by: eduabe on June 10, 2008 at 06:05 PM

  • Hmm... Sorry for my previous poorly formatted post.
    So, again, I am trying to learn more about EL and beansbinding but I am missing the connection between some old code snippets and the current version.
    How could I get the following code (from your JavaOne 2007 presentation) working with version 1.2.1??

    Binding binding = new Binding(
    bugTable,
    “${bb:listSize(selectedElements)} of” +
    “${bb:listSize(elements)} are selected”,
    summaryLabel,
    "text");

    I really appreciate your help - actually, anyone's help :)
    Thanks!

    Posted by: eduabe on June 10, 2008 at 06:13 PM

  • I'm so grateful for all that you've done. Thanks again for that nice essay and I would be most grateful if you would send me the latter ones....


    mirc
    mırc
    mirç
    mırç
    mirc indir
    chat yap
    islami sohbet
    dini sohbet
    kelebek
    kelebek sohbet
    kelebek mirc
    kameralı mirc
    kameralı sohbet
    chat yap
    çet
    çet odaları
    sohbet kanalları
    sohbet odaları
    yarışma
    sevgili
    arkadaş
    arkadaş ara
    arkadaşlık

    Posted by: jklmno on June 19, 2008 at 09:27 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds