It's *NO* bogus benchmark because the sample iterates the results. http://code.google.com/p/slim3/source/browse/trunk/slim3demo/src/slim3/demo/controller/performance/GetLLController.java
Yasuo Higa > > The code linked from http://slim3demo.appspot.com/performance/ has > just gone back to calling list.size() without iterating the results, > which once again goes back to a bogus benchmark. > > Jeff > > On Wed, Jun 8, 2011 at 9:30 PM, Yasuo Higa <higaya...@gmail.com> wrote: >> Slim3 uses LL API. >> >> To resolve a strange issue that slim3 is faster than LL, I tried the >> following samples: >> >> One: >> AsyncDatastoreService ds = >> DatastoreServiceFactory.getAsyncDatastoreService(); >> Query q = new Query("Bar"); >> PreparedQuery pq = ds.prepare(q); >> List<Entity> list = >> pq.asList(FetchOptions.Builder.withDefaults().limit( >> Integer.MAX_VALUE)); >> for (Entity e : service.getBarListUsingLL()) { >> e.getKey(); >> e.getProperty("sortValue"); >> } >> >> Two: >> AsyncDatastoreService ds = >> DatastoreServiceFactory.getAsyncDatastoreService(); >> Query q = new Query("Bar"); >> PreparedQuery pq = ds.prepare(q); >> List<Entity> list = >> pq.asList(FetchOptions.Builder.withDefaults().limit( >> Integer.MAX_VALUE)); >> >> // VERY IMPORTANT >> list.size(); >> >> for (Entity e : service.getBarListUsingLL()) { >> e.getKey(); >> e.getProperty("sortValue"); >> } >> >> The second one is much faster than the first one. >> I fixed the samples to call list.size(). >> http://slim3demo.appspot.com/performance/ >> >> As a result, LL is as fast as slim3 (^^; >> >> Yasuo Higa >> >> >> >> On Thu, Jun 9, 2011 at 10:17 AM, Jeff Schnitzer <j...@infohazard.org> wrote: >>> Thank you for fixing the benchmark. >>> >>> I am very curious. According to this new benchmark - it's hard to >>> tell without pushing the buttons a lot of times, but there seems to be >>> a trend - Slim3 is somewhat faster than the Low Level API. >>> >>> Doesn't Slim3 use the Low Level API underneath? How can it possibly be >>> faster? >>> >>> Jeff >>> >>> On Wed, Jun 8, 2011 at 4:27 PM, Yasuo Higa <higaya...@gmail.com> wrote: >>>> What I want to provide is a fair and casual benchmark. >>>> >>>> As jeff advised, I modified samples as follows: >>>> for (Entity e : service.getBarListUsingLL()) { >>>> e.getKey(); >>>> e.getProperty("sortValue"); >>>> } >>>> >>>> for (Bar bar : service.getBarListUsingSlim3()) { >>>> bar.getKey(); >>>> bar.getSortValue(); >>>> } >>>> >>>> for (BarObjectify bar : service.getBarListUsingObjectify()) { >>>> bar.getKey(); >>>> bar.getSortValue(); >>>> } >>>> >>>> for (BarJDO bar : service.getBarListUsingJDO()) { >>>> bar.getKey(); >>>> bar.getSortValue(); >>>> } >>>> >>>> LL API is much slower than before. >>>> http://slim3demo.appspot.com/performance/ >>>> >>>> Yasuo Higa >>>> >>>> >>>> On Thu, Jun 9, 2011 at 7:45 AM, Jeff Schnitzer <j...@infohazard.org> wrote: >>>>> Slim3 may be a nice piece of software, but it has not been >>>>> demonstrated to be faster than anything (including JDO). It might or >>>>> might not be faster - I don't know - but based on the sloppy >>>>> benchmarking, I'm pretty certain that the people making this claim >>>>> don't know either. >>>>> >>>>> There's another ill-conceived performance claim on the Slim3 website: >>>>> "You may worry about the overhead of global transactions. Don't worry. >>>>> It is not very expensive." There are three problems with their little >>>>> performance test: >>>>> >>>>> 1) It only measures wall-clock time, not cost. >>>>> 2) It does not measure what happens under contention. >>>>> 3) The numbers are obviously wrong - they don't even pass a smoke test. >>>>> >>>>> Look at these numbers (from the Slim3 home page): >>>>> >>>>> Entity Groups Local Transaction(millis) Global Transaction(millis) >>>>> 1 67 70 >>>>> 2 450 415 >>>>> 3 213 539 >>>>> 4 1498 981 >>>>> 5 447 781 >>>>> >>>>> Just like the 1ms low-level API query performance in the benchmark >>>>> that spawned this thread, even a casual observer should be able to >>>>> recognize the obvious flaw - the numbers don't show any expected >>>>> relationship between # of entity groups or the use of global >>>>> transactions. Interpreted literally, you would assume that local >>>>> transactions are much faster for 5 entity groups, but global >>>>> transactions are much faster for 4 entity groups. >>>>> >>>>> It's pretty obvious that the benchmark author just ran one pass and >>>>> took the numbers as-is. If you actually run multiple passes, you'll >>>>> find that there is enormous variance in the timing. The only way you >>>>> can realistically measure results like this on appengine is to execute >>>>> the test 100 times and take a median. >>>>> >>>>> FWIW, I deliberately haven't made any performance claims for Objectify >>>>> because I haven't put the necessary amount of due diligence into >>>>> creating a proper set of benchmarks. It is not easy to measure >>>>> performance, especially in a dynamic environment like appengine. I >>>>> only hope that the Slim3 authors have put more care and thought into >>>>> crafting their library than they have their benchmarks. >>>>> >>>>> Jeff >>>>> >>>>> >>>>> On Wed, Jun 8, 2011 at 2:34 PM, Gal Dolber <gal.dol...@gmail.com> wrote: >>>>>> Slim3 is not only fast, the api is completely awesome. It has been my >>>>>> choice >>>>>> for a year now for all gae projects. >>>>>> It includes "name safety" and and amazing querying utils. >>>>>> Very recommendable! >>>>>> >>>>>> On Wed, Jun 8, 2011 at 3:41 PM, Jeff Schnitzer <j...@infohazard.org> >>>>>> wrote: >>>>>>> >>>>>>> You are wrong. >>>>>>> >>>>>>> Try adding getProperty() calls to your LL performance test, and the >>>>>>> speed advantage of the LL API goes away. I don't know what to say >>>>>>> about Slim3, but here's my test case: >>>>>>> >>>>>>> >>>>>>> http://code.google.com/p/scratchmonkey/source/browse/#svn%2Fappengine%2Fperformance-test >>>>>>> >>>>>>> I created 10,000 entities in the datastore that have the same format >>>>>>> as your test case - a single string property. Here's what happens >>>>>>> (try it - and remember to reload the urls several times to get a >>>>>>> realistic median value): >>>>>>> >>>>>>> ###### Low Level API with just .size() >>>>>>> >>>>>>> http://voodoodyne.appspot.com/fetchLLSize >>>>>>> >>>>>>> The code: >>>>>>> >>>>>>> List<Entity> things = >>>>>>> DatastoreServiceFactory.getDatastoreService() >>>>>>> .prepare(new >>>>>>> Query(Thing.class.getAnnotation(javax.persistence.Entity.class).name())) >>>>>>> .asList(FetchOptions.Builder.withDefaults()); >>>>>>> things.size(); >>>>>>> >>>>>>> Note that results are almost always under 2000ms. Wild guess I'd say >>>>>>> the median elapsed is ~1900, just like your example. >>>>>>> >>>>>>> ###### Low Level API with actual fetch of the data >>>>>>> >>>>>>> http://voodoodyne.appspot.com/fetchLL >>>>>>> >>>>>>> The code: >>>>>>> >>>>>>> List<Entity> things = >>>>>>> DatastoreServiceFactory.getDatastoreService() >>>>>>> .prepare(new >>>>>>> Query(Thing.class.getAnnotation(javax.persistence.Entity.class).name())) >>>>>>> .asList(FetchOptions.Builder.withDefaults()); >>>>>>> for (Entity ent: things) >>>>>>> { >>>>>>> ent.getKey(); >>>>>>> ent.getProperty("value"); >>>>>>> } >>>>>>> >>>>>>> Note that the duration is now considerably longer. Eyeballing the >>>>>>> median elapsed time, I'd say somewhere around 3000ms. >>>>>>> >>>>>>> ###### Objectify fetching from datastore >>>>>>> >>>>>>> http://voodoodyne.appspot.com/fetch >>>>>>> >>>>>>> Objectify ofy = ObjectifyService.begin(); >>>>>>> List<Thing> things = ofy.query(Thing.class).list(); >>>>>>> for (Thing thing: things) >>>>>>> { >>>>>>> thing.getId(); >>>>>>> thing.getValue(); >>>>>>> } >>>>>>> >>>>>>> Note that the timing is pretty much the same as the LL API when it >>>>>>> includes actual fetches of the entity values. It is, no doubt, just a >>>>>>> little higher. >>>>>>> >>>>>>> ###### A pure measurement of Objectify's overhead >>>>>>> >>>>>>> http://voodoodyne.appspot.com/fakeFetch >>>>>>> >>>>>>> This causes Objectify to translate 10,000 statically-created Entity >>>>>>> objects to POJOs. You can see the code here: >>>>>>> >>>>>>> >>>>>>> http://code.google.com/p/scratchmonkey/source/browse/appengine/performance-test/src/test/FakeFetchServlet.java >>>>>>> >>>>>>> You'll notice (after you hit the URL a couple times to warm up the >>>>>>> JIT) that elapsed time converges to somewhere around 120ms. >>>>>>> >>>>>>> ----------- >>>>>>> >>>>>>> Conclusion: >>>>>>> >>>>>>> The numbers in the original benchmark are a result of improper >>>>>>> measurements. The actual wall-clock overhead for Objectify in this >>>>>>> test is ~4% (120ms out of 3000ms). >>>>>>> >>>>>>> Further speculation on my part, but probably correct: The overhead of >>>>>>> reflection is unlikely to be a significant part of that 4%. >>>>>>> >>>>>>> Sloppy work. >>>>>>> >>>>>>> Jeff >>>>>>> >>>>>>> On Wed, Jun 8, 2011 at 7:55 AM, Yasuo Higa <higaya...@gmail.com> wrote: >>>>>>> > It is not bogus. >>>>>>> > LazyList#size() fetches all data as follows: >>>>>>> > public int size() { >>>>>>> > resolveAllData(); >>>>>>> > return results.size(); >>>>>>> > } >>>>>>> > >>>>>>> > Yasuo Higa >>>>>>> > >>>>>>> > On Wed, Jun 8, 2011 at 11:32 PM, Dennis Peterson >>>>>>> > <dennisbpeter...@gmail.com> wrote: >>>>>>> >> It's not my benchmark, it's Slim3's :) ...but you're right, it's >>>>>>> >> bogus. >>>>>>> >> I >>>>>>> >> asked on the main appengine group too, and it turns out the low-level >>>>>>> >> benchmark is doing lazy loading. With that fixed, their numbers come >>>>>>> >> out >>>>>>> >> like yours. >>>>>>> >> I found this one too, which also gets results like yours: >>>>>>> >> http://gaejava.appspot.com/ >>>>>>> >> >>>>>>> >> On Wed, Jun 8, 2011 at 4:44 AM, Erwin Streur <erwin.str...@gmail.com> >>>>>>> >> wrote: >>>>>>> >>> >>>>>>> >>> Indeed Dennis's measurements are very suspicious. First you should >>>>>>> >>> do >>>>>>> >>> a couple of warming ups on each of the implementations to prevent >>>>>>> >>> pollution like the JDO classpath scan for enhanced classes (which is >>>>>>> >>> one of the reasons for the high initial run). Then do a couple of >>>>>>> >>> run >>>>>>> >>> to determine a range of measurements to spot outlyers. your >>>>>>> >>> low-level >>>>>>> >>> API 2millis is definately one. >>>>>>> >>> >>>>>>> >>> When I did the measurements I got the following results >>>>>>> >>> low-level: 1150-1550 >>>>>>> >>> Slim3: 1150-1600 >>>>>>> >>> Objectify: 1950-2400 >>>>>>> >>> JDO: 2100-2700 >>>>>>> >>> >>>>>>> >>> These measurements confirm that GAE designed implementations are >>>>>>> >>> faster then the GAE implementation of a generic data access layer >>>>>>> >>> (JDO), but not so extrem as initially posted. >>>>>>> >>> >>>>>>> >>> The initial response using JDO is a known issue and especially low >>>>>>> >>> trafic website should not use it or use the always on feature (maybe >>>>>>> >>> this will change in the new pricing model) >>>>>>> >>> >>>>>>> >>> Regards, >>>>>>> >>> >>>>>>> >>> Erwin >>>>>>> >>> >>>>>>> >>> On Jun 7, 11:00 am, Ian Marshall <ianmarshall...@gmail.com> wrote: >>>>>>> >>> > The low-level API does indeed look very fast. >>>>>>> >>> > >>>>>>> >>> > Just a comment on JDO: repeat runs roughly halve the JDO run >>>>>>> >>> > time. I >>>>>>> >>> > presume that this is because for repeat runs the JDO persistence >>>>>>> >>> > manager factory has already been constructed. >>>>>>> >>> > >>>>>>> >>> > On Jun 6, 8:44 pm, DennisP <dennisbpeter...@gmail.com> wrote: >>>>>>> >>> > >>>>>>> >>> > > I'm looking at this online >>>>>>> >>> > > demo:http://slim3demo.appspot.com/performance/ >>>>>>> >>> > >>>>>>> >>> > > Sample run: >>>>>>> >>> > > The number of entities: 10000 >>>>>>> >>> > > low-level API:get: 2 millis >>>>>>> >>> > > Slim3: 2490 millis >>>>>>> >>> > > JDO: 6030 millis >>>>>>> >>> > >>>>>>> >>> > > Is the low-level API really that much faster? >>>>>>> >>> >>>>>>> >>> -- >>>>>>> >>> You received this message because you are subscribed to the Google >>>>>>> >>> Groups >>>>>>> >>> "Google App Engine for Java" group. >>>>>>> >>> To post to this group, send email to >>>>>>> >>> google-appengine-java@googlegroups.com. >>>>>>> >>> To unsubscribe from this group, send email to >>>>>>> >>> google-appengine-java+unsubscr...@googlegroups.com. >>>>>>> >>> For more options, visit this group at >>>>>>> >>> http://groups.google.com/group/google-appengine-java?hl=en. >>>>>>> >>> >>>>>>> >> >>>>>>> >> -- >>>>>>> >> You received this message because you are subscribed to the Google >>>>>>> >> Groups >>>>>>> >> "Google App Engine for Java" group. >>>>>>> >> To post to this group, send email to >>>>>>> >> google-appengine-java@googlegroups.com. >>>>>>> >> To unsubscribe from this group, send email to >>>>>>> >> google-appengine-java+unsubscr...@googlegroups.com. >>>>>>> >> For more options, visit this group at >>>>>>> >> http://groups.google.com/group/google-appengine-java?hl=en. >>>>>>> >> >>>>>>> > >>>>>>> > -- >>>>>>> > You received this message because you are subscribed to the Google >>>>>>> > Groups "Google App Engine for Java" group. >>>>>>> > To post to this group, send email to >>>>>>> > google-appengine-java@googlegroups.com. >>>>>>> > To unsubscribe from this group, send email to >>>>>>> > google-appengine-java+unsubscr...@googlegroups.com. >>>>>>> > For more options, visit this group at >>>>>>> > http://groups.google.com/group/google-appengine-java?hl=en. >>>>>>> > >>>>>>> > >>>>>>> >>>>>>> -- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups >>>>>>> "Google App Engine for Java" group. >>>>>>> To post to this group, send email to >>>>>>> google-appengine-java@googlegroups.com. >>>>>>> To unsubscribe from this group, send email to >>>>>>> google-appengine-java+unsubscr...@googlegroups.com. >>>>>>> For more options, visit this group at >>>>>>> http://groups.google.com/group/google-appengine-java?hl=en. >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Guit: Elegant, beautiful, modular and *production ready* gwt >>>>>> applications. >>>>>> >>>>>> http://code.google.com/p/guit/ >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google Groups >>>>>> "Google App Engine for Java" group. >>>>>> To post to this group, send email to >>>>>> google-appengine-java@googlegroups.com. >>>>>> To unsubscribe from this group, send email to >>>>>> google-appengine-java+unsubscr...@googlegroups.com. >>>>>> For more options, visit this group at >>>>>> http://groups.google.com/group/google-appengine-java?hl=en. >>>>>> >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google Groups >>>>> "Google App Engine for Java" group. >>>>> To post to this group, send email to >>>>> google-appengine-java@googlegroups.com. >>>>> To unsubscribe from this group, send email to >>>>> google-appengine-java+unsubscr...@googlegroups.com. >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/google-appengine-java?hl=en. >>>>> >>>>> >>>> >>>> -- >>>> You received this message because you are subscribed to the Google Groups >>>> "Google App Engine for Java" group. >>>> To post to this group, send email to >>>> google-appengine-java@googlegroups.com. >>>> To unsubscribe from this group, send email to >>>> google-appengine-java+unsubscr...@googlegroups.com. >>>> For more options, visit this group at >>>> http://groups.google.com/group/google-appengine-java?hl=en. >>>> >>>> >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Google App Engine for Java" group. >>> To post to this group, send email to google-appengine-java@googlegroups.com. >>> To unsubscribe from this group, send email to >>> google-appengine-java+unsubscr...@googlegroups.com. >>> For more options, visit this group at >>> http://groups.google.com/group/google-appengine-java?hl=en. >>> >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Google App Engine for Java" group. >> To post to this group, send email to google-appengine-java@googlegroups.com. >> To unsubscribe from this group, send email to >> google-appengine-java+unsubscr...@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/google-appengine-java?hl=en. >> >> > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine for Java" group. > To post to this group, send email to google-appengine-java@googlegroups.com. > To unsubscribe from this group, send email to > google-appengine-java+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/google-appengine-java?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-java@googlegroups.com. To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en.