 |
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 Digg DZone Furl 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
|