Is there a reason to why you use a LineNumberReader? I would instead
use a BufferedReader, that will probably improve your performance.

I don't know anything about the dataformat in the file, but there
probably is a much faster way to parse it than using all those
StringTokenizers (or regexp even if that might be faster). I would
also try to parse the file without mark and reset.





On 20 Sep, 20:28, Glen Kimsey <gkim...@gmail.com> wrote:
> Hello!
> I'm fairly new to both Android and Java (pretty experienced in C/C++),
> and (stupidly, perhaps) took on a big project.  In it, I need to load
> information about 3D models and their respective animations from a
> text file (proprietary file format based on PSK/PSA).
>
> The loading process on a sample (1000+ line) file is abysmally slow
> (more than 4 minutes).  The good news is that there are lots and lots
> of ways I can improve it.  What I'm hoping to find out here is if
> there's anything in *particular* in my code that is very inefficient
> that I can change.  Don't worry about offending me, I know this is
> amateur code here.
>
> Some possible causes for the slowness:
> - Extensive use of parseFloat()
> - Creating new StringTokenizer for every line
> - Inefficiencies in for() loops (not caching as necessary?)
> - Repeated use of the acos() and sqrt() functions
>
> I'd like to find out from you gentlemen (ladies) what you think is the
> major thing eating up my time here.  If there's some tool I can use to
> find out what lines of code are taking up the most time that'd be
> ideal.  I'm open to any possible solutions.  The file format can
> change (and probably will).  I could even do something as drastic as
> performing this load in a separate app (before distribution) and
> somehow exporting the resulting object (KdfAnimation) that could more
> easily be picked back up (this would work in C, but I'm doubtful Java
> would allow such low-level memory copying).
>
> One final note is that the "action" loading section of this code
> occupies about 3/4 of the files being loaded (so this section may be
> more important to optimize).
>
> ====Loader Code====
> public class KdfLoader {
>
>         public static KdfAnimation load(String file) throws IOException {
>                 KdfAnimation anim = new KdfAnimation();
>
>                 FileInputStream fis = new FileInputStream(file);
>                 String line = "[start]";
>                 LineNumberReader lnr = new LineNumberReader(new 
> InputStreamReader
> (fis));
>
>                 int boneNum = 0;
>
>                 try {
>
>                 for (line = lnr.readLine(); line != null; line = 
> lnr.readLine()) {
>                         if (line.length() > 0) {
>                                 if (line.startsWith("numbones")) {
>                                         // Ignore it for now
>                                 }
>                                 else if (line.startsWith("bone")) {
>                                         // Bone define
>                                         StringTokenizer tok = new 
> StringTokenizer(line);
>                                         KdfBone bone = new KdfBone();
>
>                                         // Toss out "bone"
>                                         tok.nextToken();
>
>                                         // Set name
>                                         bone.boneName = tok.nextToken();
>
>                                         if (boneNum == 0) {
>                                                 // Root bone.  Ignore 
> children and parent id in file
>                                                 bone.parentId = 0;
>                                                 bone.parent = null;
>                                                 // ignore "numchildren x"
>                                                 // ignore "parentid x"
>                                         }
>                                         else
>                                         {
>                                                 // ignore "numchildren x"
>                                                 tok.nextToken();
>                                                 tok.nextToken();
>                                                 // ignore "parentid" text
>                                                 tok.nextToken();
>                                                 bone.parentId = 
> Integer.parseInt(tok.nextToken());
>                                                 bone.parent = 
> anim.allBones.get(bone.parentId);
>                                         }
>                                         // get loc and rot
>                                         line = lnr.readLine();
>                                         bone.loc = parseLocLine(line);
>                                         line = lnr.readLine();
>                                         bone.rot = parseRotLine(line);
>
>                                         // Handle explicit linkage
>                                         while(true) {
>                                                 lnr.mark(1000);
>                                                 line = lnr.readLine();
>                                                 if (line.startsWith("obj")) {
>                                                         tok = new 
> StringTokenizer(line);
>                                                         // ignore "obj"
>                                                         tok.nextToken();
>                                                         
> bone.partLinks.add(tok.nextToken());
>                                                         
> anim.explicitPartLinkage = true;
>                                                 }
>                                                 else {
>                                                         // Reset to previous 
> line number
>                                                         lnr.reset();
>                                                         break;
>                                                 }
>                                         }
>
>                                         // Add bone to animation
>                                         if (boneNum == 0) {
>                                                 anim.rootBone = bone;
>                                         }
>                                         else {
>                                                 // Add this bone to its 
> parent's list of children
>                                                 
> bone.parent.children.add(bone);
>                                         }
>                                         anim.allBones.add(bone);
>
>                                         boneNum++;
>                                 }
>                                 else if (line.startsWith("action")) {
>                                         // Action define
>                                         StringTokenizer tok = new 
> StringTokenizer(line);
>                                         KdfAction action = new KdfAction();
>
>                                         // ignore "action"
>                                         tok.nextToken();
>
>                                         // Set name
>                                         action.actionName = tok.nextToken();
>
>                                         // ignore "numframes" text
>                                         tok.nextToken();
>
>                                         // Get number of frames
>                                         action.numberOfFrames = 
> Integer.parseInt(tok.nextToken());
>
>                                         // Get all bone actions
>                                         while(true) {
>                                                 //Mark the current line
>                                                 lnr.mark(1000);
>                                                 line = lnr.readLine();
>                                                 if (line == null) {
>                                                         break;
>                                                 }
>                                                 if (!line.startsWith("bone")) 
> {
>                                                         // Go back to the 
> previous line so the for() loop we're in
> doesn't skip one
>                                                         lnr.reset();
>                                                         break;
>                                                 }
>
>                                                 KdfBoneAction bact = new 
> KdfBoneAction();
>
>                                                 tok = new 
> StringTokenizer(line);
>                                                 // ignore "bone"
>                                                 tok.nextToken();
>
>                                                 // Figure out the bone this 
> using
>                                                 String boneName = 
> tok.nextToken();
>                                                 for (int i = 0; i < 
> anim.allBones.size(); i++) {
>                                                         if 
> (anim.allBones.get(i).boneName.equalsIgnoreCase(boneName)) {
>                                                                 bact.bone = 
> anim.allBones.get(i);
>                                                                 break;
>                                                         }
>                                                 }
>
>                                                 // Get [numberOfFrames] locs
>                                                 for (int i = 0; i < 
> action.numberOfFrames; i++) {
>                                                         line = lnr.readLine();
>                                                         
> bact.locs.add(parseLocLine(line));
>                                                 }
>
>                                                 // Get [numberOfFrames] rots
>                                                 for (int i = 0; i < 
> action.numberOfFrames; i++) {
>                                                         line = lnr.readLine();
>                                                         
> bact.rots.add(parseRotLine(line));
>                                                 }
>
>                                                 // Add the BoneAction to the 
> action
>                                                 action.boneActions.add(bact);
>                                         }
>
>                                         // Add the action to the animation
>                                         anim.actions.add(action);
>                                 }
>                         }
>                 }
>
>                 } catch (Exception e) {
>                         System.err.println("Error parsing file:");
>                         System.err.println(lnr.getLineNumber()+" : "+line);
>                 }
>
>                 return anim;
>         }
>
>         private static float[] parseLocLine(String line) {
>                 float[] retFloat = new float[3];
>                 StringTokenizer tok = new StringTokenizer(line);
>
>                 // Ignore "loc"
>                 tok.nextToken();
>                 // x
>                 tok.nextToken();
>                 retFloat[0] = Float.parseFloat(tok.nextToken());
>                 // y
>                 tok.nextToken();
>                 retFloat[1] = Float.parseFloat(tok.nextToken());
>                 // z
>                 tok.nextToken();
>                 retFloat[2] = Float.parseFloat(tok.nextToken());
>
>                 return retFloat;
>         }
>
>         private static float[] parseRotLine(String line) {
>                 float[] retFloat = new float[4];
>                 StringTokenizer tok = new StringTokenizer(line);
>
>                 // Ignore "rot"
>                 tok.nextToken();
>                 // theta
>                 tok.nextToken();
>                 retFloat[0] = wToTheta(Float.parseFloat(tok.nextToken()));
>                 // x
>                 tok.nextToken();
>                 retFloat[1] = Float.parseFloat(tok.nextToken());
>                 // y
>                 tok.nextToken();
>                 retFloat[2] = Float.parseFloat(tok.nextToken());
>                 // z
>                 tok.nextToken();
>                 retFloat[3] = Float.parseFloat(tok.nextToken());
>
>                 // Need to scale this vector to make glRotate happy
>                 retFloat = scaleAxisAngleVector(retFloat);
>
>                 return retFloat;
>         }
>
>         private static float wToTheta(float w) {
>                 // w = cos(theta/2)
>                 float theta = (float)Math.acos((double)w) * 2;
>                 // convert theta to degrees
>                 theta = 180 * theta / (float)Math.PI;
>                 // The above calculation only gave us a value from 0 to 180 
> because
> of arccosine
>                 // TODO: Determine if this is a problem.  Note that w can be
> negative, and this implies 180 degrees
>                 if (w < 0) {
>                         theta += 180;
>                 }
>                 return theta;
>         }
>
>         private static float[] scaleAxisAngleVector(float[] unscaled) {
>                 float[] scaled = new float[4];
>                 // scale = sqrt(x^2 + y^2 + z^2);
>                 float scale = (float)Math.sqrt(unscaled[1] * unscaled[1] + 
> unscaled
> [2] * unscaled[2] + unscaled[3] * unscaled[3]);
>
>                 if (scale != 0) {
>                         scaled[0] = unscaled[0];
>                         scaled[1] = unscaled[1] / scale;
>                         scaled[2] = unscaled[2] / scale;
>                         scaled[3] = unscaled[3] / scale;
>                 }
>                 else
>                 {
>                         // Scale can be 0, which means we're not rotating
>                         // but dividing by zero is bad, and glRotate still
>                         // needs a normalized vector.
>                         scaled[0] = 0;
>                         scaled[1] = 1;
>                         scaled[2] = 0;
>                         scaled[3] = 0;
>                 }
>                 return scaled;
>         }}
>
> ====End of Loader Code====
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Beginners" group.
To post to this group, send email to android-beginners@googlegroups.com
To unsubscribe from this group, send email to
android-beginners-unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to