Some help with Optimization
Some help with Optimization
- Subject: Some help with Optimization
- From: Owen McKerrow <email@hidden>
- Date: Fri, 10 Feb 2006 10:00:31 +1100
Hi All,
Im trying to figure out a way to optimize a section of my app, that
is figure out where the bad design is that is causing the slow down.
In a nut shell I have an array of 1800 objects which I then do a key-
value coding call on to get another array, the key-value call takes
10 seconds, Im assuming that it shouldn't take so long.
OK now for some details :
OS X 10.4.4
Java 1.4.2
WO 5.2.4
OpenBase 8
Objective : To get the full list of External Authors active names.
DB setup :
Person <- ->> PersonName ( so a person can have many names thus
allowing for name changes, while keeping the old name for historic
time snap shots )
EOModel set up :
Person Table :
Batch Faulting Size : 100
Relationship personNames : To Many, Inner, Optional, Batch Size 100.
PersonName table :
Batch Faulting Size : 100
Relationship personNames : To One, Inner, Mandetory
External inherits from Person via Single Table Mapping.
So in my Person class I have a function for getting the currently
active name :
public PersonName activeName()
{
int i;
PersonName theName= null;
for (i=0;i<personNames().count();i++) {
PersonName temp = (PersonName)personNames().objectAtIndex(i);
if ( temp.active().intValue() == 1 ) {
theName = temp;
break;
}
}
return theName;
}
Is there an easier/quicker way to do this ? Should I have a second to-
one relationship which is for the active name ? I should note that
there about 5 people in the DB which actually have more than 1 name,
so in 98ish% of cases this is returns the first object.
In my External entity I have a fetch spec called "allMembers" which
has no values in the qualifier ( thus getting all objects), a sort
order of personNames.lastName, it performs deep inheritance fetch and
only fetches distinct rows.
So in the constructor of the page I have the following :
System.out.println("Get Authors :" + new NSTimestamp());
NSArray tempAllExs = (NSArray)
EOUtilities.objectsWithFetchSpecificationAndBindings
(ec,"External","allMembers",new NSMutableDictionary());
System.out.println("Get names via value for key :" + new NSTimestamp());
selectableExtenals = (NSArray)tempAllExs.valueForKey("activeName");
System.out.println("End :" + new NSTimestamp());
Which results in :
Get Authors :2006-02-09 21:50:46 Etc/GMT
Get names via value for key :2006-02-09 21:50:47 Etc/GMT
End :2006-02-09 21:50:57 Etc/GMT
As you can see there's 10 seconds to do the valueForKey bit.
Turning on SQL logging and I find that when I do the valuforKey look
up its going back to the DB to get all the names. Now I would have
thought it would have gotten the names when it got the External's
from the first call, as I had set the personName batch size to 100 ?
Then again this will only happen when it fires the first fault, i.e.
I try and use a personName. In fact when I re look over the SQL I
find that
SELECT t0.active, t0.creationDate, t0.firstName, t0.initial,
t0.lastName, t0.personID, t0._rowid FROM PERSON_NAME t0, PERSON T1 WHERE
gets called in total 24 times. So batch faulting is set to 100. There
is 1836 records, so I would have thought 9 times ( to get all the
objects in batches of 100 ). But instead it seems to be calling it in
lots of 8, 3 times. Should I set my batch sizes bigger now that Im
dealing with a larger data set ? What is to large a batch? i.e. if I
set it to say 2000 is that just being stupid ? I actually just went
and tried this and with batch sizes set to 2000 I still get 10 seconds.
Anyways 10 seconds still seems like a long time even if it does need
to get the info from the DB.
I have tried going straight to the PersonName table :
System.out.println("Get Authors :" + new NSTimestamp());
selectableExtenals = (NSArray)
EOUtilities.objectsWithFetchSpecificationAndBindings
(ec,"PersonName","getExternals",null);
System.out.println("End :" + new NSTimestamp());
where "getExternals" has the qualifier ((active = 1) and
(person.type = 4)), however this in fact takes longer ( 36 seconds )
as it fires 1 fault for every person object. i.e. gets all the names
nicely, but then gets each associated external object from the
database 1 at a time.
Get Authors :2006-02-09 22:44:03 Etc/GMT
End : 2006-02-09 22:44:39 Etc/GMT
So Im seeing a couple of places where I may be able to make things
quicker. Replace the activeName() function with a real relationship,
increase the size of batches requested or figure out why going from
the PersonName table causes every fault to External to fire separately.
Any help/advice would be most welcome.
Thanks all,
Owen McKerrow
WebMaster, emlab
http://emlab.uow.edu.au
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
People who prefer typing to pointing then seem to prefer acronyms to
save typing :-)
-Denis Stanton, On people using Command Line Interfaces
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden