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

rdmd: compile the root module in the same step as getting the dependencies #194

Merged
merged 5 commits into from Aug 28, 2016

Conversation

aG0aep6G
Copy link
Contributor

As suggested by Andrei in a comment on #191. Consequently, this is an alternative to #191.

Little benchmark

Used bash's builtin time with TIMEFORMAT=%R to get simple output.
All times are the best of 3 runs.
rdmd_master is the current master (1260719).
rdmd_single_out_root is the one from this PR.
foo.d is http://sprunge.us/ZZhR, taken from #191.

single file

$ time ./rdmd_master --force foo.d > /dev/null
1.142
$ time ./rdmd_single_out_root --force foo.d > /dev/null
0.747

Good improvement here.

trivial root, complex import

bar.d is import foo;.

$ time ./rdmd_master --force bar.d > /dev/null
0.935
$ time ./rdmd_single_out_root --force bar.d > /dev/null
0.937

As expected, no change here.

complex root, trivial import

baz.d is foo.d plus import qux;.
qux.d is an empty file.

$ time ./rdmd_master --force baz.d > /dev/null
1.144
$ time ./rdmd_single_out_root --force baz.d > /dev/null
0.763

This is improving too, because the root isn't compiled again when the import is compiled.

reuse cached executable

$ time ./rdmd_master foo.d > /dev/null
0.013
$ time ./rdmd_single_out_root foo.d > /dev/null
0.012

No bad surprise here.

This avoids calling dmd twice when running a single file, which is a common
task.
@dlang-bot
Copy link
Contributor

@aG0aep6G, thanks for your PR! By analyzing the annotation information on this pull request, we identified @CyberShadow, @andralex and @NilsBossung to be potential reviewers. @CyberShadow: The PR was automatically assigned to you, please reassign it if you were identified mistakenly.

(The DLang Bot is under development. If you experience any issues, please open an issue at its repo.)

@wilzbach
Copy link
Member

As suggested by Andrei in a comment on #191. Consequently, this is an alternative to #191.

Oh nice - I did the same too, but didn't publish it yet because I wanted to test it further & do more cleanup ;/

string[] objs = [ rootObj ];

// compile dependencies
if (myDeps.byValue.any) // if there is any source dependency at all
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a difference between using .byValue.any and .length > 0 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

myDeps is a string[string]. .byValue.any is false when there are values but they're all null. Null values are set for non-source dependencies (lines 656-683).

But maybe this should check against emptiness instead. It's easy to forget that null has a different truthiness than empty strings.

Copy link
Member

Choose a reason for hiding this comment

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

That's quite a clever trick to check for "external" source files!

But maybe this should check against emptiness instead. It's easy to forget that null has a different truthiness than empty strings.

Yep better use .any!"a !is null", then it's at least consistent with the query below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep better use .any!"a !is null", then it's at least consistent with the query below.

I think that's the same as just .any. But it's clearer with an explicit !is null, so I changed it. I did o => o !is null though, because I don't like string predicates.

@AndrejMitrovic
Copy link
Contributor

Cool stuff! It gets my LGTM.

auto depsGetter = [ compiler ] ~ compilerFlags ~ [
"-v",
"-c",
"-of"~buildPath(objDir, "rdmd.root"~objExt),
Copy link
Member

Choose a reason for hiding this comment

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

I used exeBasename as the filename is shown in the error message

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 used exeBasename as the filename is shown in the error message

Seems like a good idea. Done.

The problem I had worked around here was that dmd would also write to foo.o when -main is passed in the linking command.

I've now changed it to pass -main when compiling the root module. But there seems to be a bug in dmd with -main -c -of: issue 16440. So I've reverted to rdmd's old style of doing --main: stubmain.d.

@wilzbach
Copy link
Member

wilzbach commented Aug 28, 2016

It's too late today for me to really look at rdmd.d anymore. Yours here seems to be more extensive than mine. So you may have caught details that I missed.

In the short version: You directly modified the source dependency checking function to emit an object file, whereas I went a rather long road that removes this function completely and refactored quite a bit on the way.

PR duel!

After comparing our approaches I think yours is better because it touches a lot less lines - great job!
If I find time, I will port my refactorings to the future master.

I already added a couple of comments, but there is one interesting thing in the benchmarks I did at #195 - your binary is 0.1MB larger and it takes 1ms longer to run on all benchmarks.
I store the information whether there are other source files directly while dependency file is read, might this explain the 1ms difference?

edit: just to clarify - the approach #195 is the same and thus I can backup the benchmarks and improved performance.

Moving --main functionality from linking to compilation of root module so
that dmd doesn't mess with the object files.
@aG0aep6G
Copy link
Contributor Author

I already added a couple of comments, but there is one interesting thing in the benchmarks I did at #195 - your binary is 0.1MB larger and it takes 1ms longer to run on all benchmarks.
I store the information whether there are other source files directly while dependency file is read, might this explain the 1ms difference?

Are you sure that you can detect a 1ms difference? On my machine, two runs of the same binary usually differ by more than 1ms.

I've ran your benchmark script a couple times, and the results weren't really conclusive. Sometimes #195 was faster, other times #194 was faster. The difference was always only a couple ms. Two runs of the same binary had a similar variance.

@@ -470,46 +479,58 @@ private int rebuild(string root, string fullExe,
}
}

auto fullExeTemp = fullExe ~ ".tmp";
immutable fullExeTemp = fullExe ~ ".tmp";
immutable rootObj = buildPath(objDir, root.baseName(".d")~objExt);
Copy link
Member

Choose a reason for hiding this comment

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

spaces around ~ please

@andralex
Copy link
Member

Good work, I approve modulo a few nits. Thanks!!

@aG0aep6G
Copy link
Contributor Author

Good work, I approve modulo a few nits. Thanks!!

Added spaces around ~ (but only at the ones I'm introducing or touching anyway). That was the only nit, right?

@andralex
Copy link
Member

thx!

@andralex
Copy link
Member

This is definitely worth a changelog entry and hopefully also a blog entry.

@andralex andralex merged commit a63233c into dlang:master Aug 28, 2016
@wilzbach
Copy link
Member

This is definitely worth a changelog entry and hopefully also a blog entry.

Ping @mdparker - we had quite a fun weekend here. Maybe you can interview @aG0aep6G?

@mdparker
Copy link
Member

If @aG0aep6G sends me an email (I can't find any contact info), we can start talking about a blog post. I'm eager to do so.

@aG0aep6G
Copy link
Contributor Author

If @aG0aep6G sends me an email (I can't find any contact info), we can start talking about a blog post. I'm eager to do so.

My email is ag0aep6g@gmail.com. Though, I'm not sure if I can give much interesting insight. After all, combining -c with -v was Vladimir's/Andrei's idea.

@aG0aep6G aG0aep6G deleted the rdmd-single-out-root branch August 31, 2016 12:44
@CyberShadow
Copy link
Member

This pull request introduced a regression:
https://issues.dlang.org/show_bug.cgi?id=16978

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.

None yet

7 participants