Re: Threads and findUsingPrototype
[email protected] Sat, 07 Nov 2009 12:19:15 +1000
| Newsgroups | gmane.comp.java.orm.simpleorm |
|---|---|
| Message-ID | <[email protected]> |
Hello John, THREADING Your threading approach is OK. In normal operation, you would have one session per thread, one thread per session. This can be overridden in special cases, but normally there are sanity checks to ensure that it is the case. Sharing a JDBC connection between threads is certainly asking for deep trouble. Queing the SDataSets is a reasonable approach. There are examples in the LongTransactionTest as to how to detach and reattach SDataSets. An alternative would be to simply have two threads, each of which does the reading and the processing, and then synchronize to ensure that only one ever does critical processing at a time. Avoids need for a queue. But generally, I would not introduce complex architectures for maximum gain of only 30%. More importantly, can the processing itself be multi threaded? You have not indicated the application, so hard for me to know. But a quad core machine might increase throughput by 400%, much better than 30% improvement. One way to go much faster is to use a Java embeded database. HSQL, for example can be well over 1000% faster than Oracle. Daffodil, H2 and JavaDB are probably more reliable, have not tested for speed. But again, if the database is only consuming 30% of your time, then maybe not worth it. And of course Stored Procedures will be much faster where applicable. And of course, make sure you are using the "server" JVM to compile properly. FIND USING PROTOTYPE findUsingPrototype is deprecated because we do not want people using it directly, but it is public because it provides a back door from SSessionJdbc to avoid creating an object. The main method is find(meta, keys...). But we have not found it to be slow -- the overhead of a couple of temporary objects is negligible. Are you sure that it really is a significant bottle neck for you? We could make a special case of the common case of a single primary key. But I prefer to avoid special cases unless a significant performance benefit could be demonstrated. (The changes would mainly be in SDataSet. Eg. in find() if (keys.count() == 1) records.get(key); Bit fiddly because HashTable does key.equals(k) instead of k.equals(key), so the single key case would be quite different indeed and need to be implemented consistently.) (One thing that is slow is the standard Java implementation of HashMap. It creates an Entry object for each entry instead of using odd and even slots in the array. In our case the key and the value are both the same object. If you felt like writing a new HashMap implementation that could help a bit. But unfortunately it cannot implement Map, which has the Entry object implicitly built into it (very bad design of a core element).) Hope this helps, Anthony At 02:56 AM 4/11/2009, you wrote: > > >I tried to post the message below on Oct 30 but I sent it from the wrong address, so it didn't get through. > >Since then, we haven't had any ideas on how to replace findUsingPrototype, and would welcome any thoughts on it. (It's deprecated, so there must be some thoughts to be shared...) > >However, we have made some progress on understanding the threading. It seems the design is to have one session per thread, and one (or zero) session per dataset, and one current dataset per session. Is that correct? > >If that is the design, then we'd like to have two threads that have their own sessions, that create datasets containing batches of records. The batches of records (and their associated datasets) would be disassociated from the session, then put in a queue for the main thread to process, and ultimately destroy. > >We don't want to create sessions for each batch, just datasets for each batch. So we'd need to create a new dataset for the session after the current dataset has been disassociated from the session (haven't figured out how to do this yet.) > >We'd appreciate any comments or suggestions on how to replace findUsingPrototype (it's too slow) and on how to best use SimpleORM in a multithreaded application. > >-- >John Abraham ><mailto:jabraham%40ucalgary.ca>[email protected] > >************* >** Original message (that didn't make it to the list on Friday Oct 30) ** > >Hello there. We have been working at speeding up our SimpleORM project which processes 65 million records in sequence, in about 4000 batches. We've profiled the code (using hprof) and would like to do two things now to increase performance: > >1) we'd like to spin off two threads to pre-fetch batches of records (average batch size 65,000,000/4000 = 16,250) and put the resulting ArrayLists of SRecordInstances in a FIFO queue. That way we can process previous batches of records off the head of the queue on a separate processor while the database is engaged fetching the next batches for the tail of the queue. The Java program spends about 30% of its time waiting for the database to return the next batch and even more time (about 8%) for SimpleORM to create the resulting ArrayList; we might as well ask for a few batches in advance. Question: is SimpleORM thread safe for this type of operation? > >2) findUsingPrototype is quite slow for repeated finds of prefetched records: SDataSet.findOrCreate() has to create the prototype object, then SDataSet.finder() has to populate its fields, then there is the processing of SRecordInstance.equals() and SRecordInstance.hashCode() to find the record in the cache. All of these together are, I think, about 30% of our runtime. Is there a way to speed this up? I notice findUsingPrototype() is deprecated, suggesting that someone already has a new plan for how to do this. For some of our tables we know the underlying data is static, so our current plan is to build our own faster hashmaps for certain types of records (especially those with a single integer primary key), and check our own cache first before checking SimpleORM's cache. But I'd rather s peed up SimpleORM than work around it. > >So those are my two questions: 1) Threadsafe? 2) are there already ideas or bits of code to replace findUsingPrototype() with something faster? > > Dr Anthony Berglas, [email protected] Mobile: +61 4 4838 8874 Just because it is possible to push twigs along the ground with ones nose does not necessarily mean that is the best way to collect firewood. ------------------------------------ Yahoo! Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/SimpleORM/ <*> Your email settings: Individual Email | Traditional <*> To change settings online go to: http://groups.yahoo.com/group/SimpleORM/join (Yahoo! ID required) <*> To change settings via email: [email protected] [email protected] <*> To unsubscribe from this group, send an email to: [email protected] <*> Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/
aa7a5a8.jpg
(image/jpeg, 3.3 KB) - not displayed