-
-
Notifications
You must be signed in to change notification settings - Fork 143
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
Conversation
This avoids calling dmd twice when running a single file, which is a common task.
@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. |
string[] objs = [ rootObj ]; | ||
|
||
// compile dependencies | ||
if (myDeps.byValue.any) // if there is any source dependency at all |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
Cool stuff! It gets my LGTM. |
auto depsGetter = [ compiler ] ~ compilerFlags ~ [ | ||
"-v", | ||
"-c", | ||
"-of"~buildPath(objDir, "rdmd.root"~objExt), |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
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.
After comparing our approaches I think yours is better because it touches a lot less lines - great job! I already added a couple of comments, but there is one interesting thing in the benchmarks I did at #195 - your binary is 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.
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spaces around ~
please
Good work, I approve modulo a few nits. Thanks!! |
Added spaces around |
thx! |
This is definitely worth a changelog entry and hopefully also a blog entry. |
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 |
This pull request introduced a regression: |
As suggested by Andrei in a comment on #191. Consequently, this is an alternative to #191.
Little benchmark
Used bash's builtin
time
withTIMEFORMAT=%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
Good improvement here.
trivial root, complex import
bar.d is
import foo;
.As expected, no change here.
complex root, trivial import
baz.d is foo.d plus
import qux;
.qux.d is an empty file.
This is improving too, because the root isn't compiled again when the import is compiled.
reuse cached executable
No bad surprise here.