Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimizations from profiling build_hyracks #68

Conversation

jakebiesinger
Copy link
Contributor

@anbangx @Nan-Zhang @JavierJia @Elmira88

Some simple changes to our code after looking at the profiles of BUILD_HYRACKS. the enum.values() function was apparently still doing a lot of work (or was being called so many times as to make it seem that way). I swapped it with a static final array of the same name.

6f40f96 will cause more GC overhead but it's negligible compared to the deepcopy cost. I'm running timings now and will update this when I have them.

A few other items I noticed:

  • 50% of the time is in writing but 1/2 of that time is actually spent in *.getSerializedLength()! We may want to cache the length or something!
  • iterating over the treesets takes a looong time. TreeSet iterators are by far our most costly operation.

@@ -148,7 +148,7 @@ public static void writeHDFSBinToHDFSSvg(JobConf conf, String srcDir, String des

public static String convertEdgeToGraph(String outputNode, Node value, GRAPH_TYPE graphType) {
String outputEdge = "";
for (EDGETYPE et : EDGETYPE.values()) {
for (EDGETYPE et : EDGETYPE.values) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain the different between the values() and value ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

values() is a function that's automatically generated for all enum types and which returns a static final array including all the enum values (so FF, FR, RF and RR in this case). values as I've added here is shadowing that generated function with a public static final enum[]. I'm essentially bypassing the getter for this enum type, which was taking up to 5% of the total runtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can rename away from .values so it's not so ambiguous. In fact, it's weird that java lets me have a field called values when I can also call the function values().

@JavierJia
Copy link
Collaborator

About this

50% of the time is in writing but 1/2 of that time is actually spent in *.getSerializedLength()! We may want to cache the length or something!

I suggest we remove this method, because every time we serialized node, we call this

public byte[] marshalToByteArray() throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(getSerializedLength());
        DataOutputStream out = new DataOutputStream(baos);
        write(out);
        return baos.toByteArray();
    }

When the caller want to know the length, just let it to get the length of the returned byte[].

@JavierJia
Copy link
Collaborator

About the iterator issues, the TreeSet.iterator is really complicated. By now , we didn't use some range query operations, maybe we can just change it to HashSet ?

@jakebiesinger
Copy link
Contributor Author

When the caller want to know the length, just let it to get the length of the returned byte[].

Good point. I had thought that this code was called directly by pregelix/hyracks. Turns out that we control the caller in this case so we can do it. Looking at the API for ByteArrayOutputStream, I see that it wil handle growing if it needs to as well. So we truly don't need this funciton. Good catch.

@jakebiesinger
Copy link
Contributor Author

About the iterator issues, the TreeSet.iterator is really complicated. By now , we didn't use some range query operations, maybe we can just change it to HashSet

Yeah, that's an easy fix. The only thing we lose is a syntactically clear way to get the (one and) only element in the set.

@jakebiesinger
Copy link
Contributor Author

Total graph build time with one thread goes from 26.5 to 23 minutes, so about 10% savings.

@JavierJia
Copy link
Collaborator

this 10% saving is decreased by this branch ? or iterator() ? or getlength?

@jakebiesinger
Copy link
Contributor Author

When the caller want to know the length, just let it to get the length of the returned byte[].

Good point. I had thought that this code was called directly by pregelix/hyracks. Turns out that we control the caller in this case so we can do it. Looking at the API for ByteArrayOutputStream, I see that it wil handle growing if it needs to as well. So we truly don't need this funciton. Good catch.

We still have to call the EdgeMap.getLenghtInBytes() on any copy operation. I could try caching the value and marking it dirty when there's an update. Or maybe we stop caring at this point.

@jakebiesinger
Copy link
Contributor Author

this 10% saving is decreased by this branch ? or iterator() ? or getlength?

10% saving just from the changes committed so far. I'm working on the other changes now and will post timings once they're ready.

@JavierJia
Copy link
Collaborator

OK, I got it.

@anbangx anbangx closed this Nov 21, 2013
@jakebiesinger jakebiesinger reopened this Nov 21, 2013
@jakebiesinger
Copy link
Contributor Author

@anbangx don't close the pull request, please :D

@anbangx
Copy link
Collaborator

anbangx commented Nov 21, 2013

😄

@jakebiesinger
Copy link
Contributor Author

Looks like 10% savings before was a fluke run. After running several times on the previous code, I see 5% on average. I've now pushed a fix for getLengths() and will do some timings and will switch over to HashSets instead of TreeSets.

@Nan-Zhang
Copy link
Collaborator

can we write a our own parsing function instead of using regex?, and can
consider the 'N'

On Thu, Nov 21, 2013 at 12:56 PM, Jake Biesinger
[email protected]:

Looks like 10% savings before was a fluke run. After running several times
on the previous code, I see 5% on average. I've now pushed a fix for
getLengths() and will do some timings and will switch over to HashSets
instead of TreeSets.


Reply to this email directly or view it on GitHubhttps://github.com//pull/68#issuecomment-29023631
.

@jakebiesinger
Copy link
Contributor Author

can we write a our own parsing function instead of using regex?, and can
consider the 'N'

Yes... but why? You think it will be faster than the regex? Or you mean you want to special-case the N character as I mentioned in #69?

@jakebiesinger
Copy link
Contributor Author

Okay guys, I think I'm done optimizing/profiling for a while. I'll do some timings on all these changes later but from my profiling, the remaining overhead is hyracks/pregelix code.

Timing tables for BUILD:

Ordered by Own Time:

selection_004

Ordered by Total Time:

selection_005

Timing tables for MERGE:

Ordered by Own Time:

selection_003

Ordered by Total Time:

selection_002

@jakebiesinger
Copy link
Contributor Author

Timings are in:
genomix/fullstack_genomix - BUILD,HYRACKS - 38.47 min
wbiesing/optimizations-from-profiling-BUILD_HYRACKS - BUILD,HYRACKS - 33.10665 minutes

so 16% faster. Not huge but a decent speedup :) Any comments? Shall I merge it in?

@JavierJia
Copy link
Collaborator

Great. LGTM. :+1

Best Regards.

Jianfeng Jia
PhD student of Computer Science
University of California, Irvine

On Nov 23, 2013, at 3:54 PM, Jake Biesinger [email protected] wrote:

Timings are in:
genomix/fullstack_genomix - BUILD,HYRACKS - 38.47 min
wbiesing/optimizations-from-profiling-BUILD_HYRACKS - BUILD,HYRACKS - 33.10665 minutes

so 16% faster. Not huge but a decent speedup :) Any comments? Shall I merge it in?


Reply to this email directly or view it on GitHub.

…wbiesing/optimizations-from-profiling-BUILD_HYRACKS

Conflicts:
	genomix/genomix-
pregelix/src/main/java/edu/uci/ics/genomix/pregelix/io/VertexValueWritable.java
	genomix/genomix-
pregelix/src/main/java/edu/uci/ics/genomix/pregelix/operator/DeBruijnGraphCleanVertex.java
jakebiesinger added a commit that referenced this pull request Dec 3, 2013
…iling-BUILD_HYRACKS

optimizations from profiling build_hyracks
@jakebiesinger jakebiesinger merged commit 587d70b into genomix/fullstack_genomix Dec 3, 2013
@jakebiesinger jakebiesinger deleted the wbiesing/optimizations-from-profiling-BUILD_HYRACKS branch December 3, 2013 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants