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

Small performance increase for std.conv.text/wtext/dtext #4280

Merged
merged 1 commit into from
Jul 14, 2016

Conversation

JackStouffer
Copy link
Member

Saves about 5 - 7 hnsecs.

}
else
{
auto app = appender!S();
Copy link
Member

Choose a reason for hiding this comment

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

if args.length == 1 this will be slower I guess

@JackStouffer
Copy link
Member Author

@DmitryOlshansky Fixed

@DmitryOlshansky
Copy link
Member

Saves about 5 - 7 hnsecs.

How do you measure it?

@JackStouffer
Copy link
Member Author

@DmitryOlshansky

import std.stdio;
import std.datetime;
import std.conv;

enum testCount = 1_000_000;

S textImpl(S, U...)(U args)
{
    static if (U.length == 0)
    {
        return null;
    }
    else
    {
        auto result = to!S(args[0]);
        foreach (arg; args[1 .. $])
            result ~= to!S(arg);
        return result;
    }
}

S textImpl2(S, U...)(U args)
{
    static if (U.length == 0)
    {
        return null;
    }
    else
    {
        import std.array : appender;

        if (__ctfe)
        {
            auto result = to!S(args[0]);
            foreach (arg; args[1 .. $])
                result ~= to!S(arg);
            return result;
        }
        else
        {
            auto app = appender!S();
            app.reserve(U.length * S.sizeof);

            foreach (arg; args)
                app.put(to!S(arg));
            return app.data;
        }
    }
}

void main()
{
    auto result = to!Duration(benchmark!(() => textImpl!dstring(42, ' ', 1.5, ": xyz", 333, "Another test"))(testCount)[0] / testCount);
    auto result2 = to!Duration(benchmark!(() => textImpl2!dstring(42, ' ', 1.5, ": xyz", 333, "Another test"))(testCount)[0] / testCount);

    writeln("result", "\t", result);
    writeln("result2", "\t", result2);
}

@JackStouffer
Copy link
Member Author

I really don't see why the auto tester is failing.

else
{
auto app = appender!S();
app.reserve(U.length * S.sizeof);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why S.sizeof? As far as I see, it's just an arbitrary number, determined by rule of thumb, and using S.sizeof for this suggests a relation where there is none.

@aG0aep6G
Copy link
Contributor

aG0aep6G commented May 4, 2016

Are you sure it's Appender that fails CTFE, and not to!S?

@aG0aep6G
Copy link
Contributor

aG0aep6G commented May 4, 2016

I really don't see why the auto tester is failing.

Compiler bug. Filed it here: https://issues.dlang.org/show_bug.cgi?id=15992

@JackStouffer
Copy link
Member Author

JackStouffer commented May 4, 2016

Why S.sizeof?

|
|

Are you sure it's Appender that fails CTFE, and not to!S?

Yeah, not sure what I was thinking there. This never worked at CTFE.

Still creating one string per argument. How about using std.format.formatValue to format directly into the appender?

It's not @safe, and therefore it breaks a bunch of test in std.datetime. Also, I don't know if it's a good idea to make this unsafe in general.

@aG0aep6G
Copy link
Contributor

aG0aep6G commented May 5, 2016

It's not @safe, and therefore it breaks a bunch of test in std.datetime. Also, I don't know if it's a good idea to make this unsafe in general.

I see. Yeah, no, let's keep things @safe.

return result;
import std.array : appender;

if (__ctfe)
Copy link
Member

Choose a reason for hiding this comment

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

appender should work in ctfe thought

@JackStouffer
Copy link
Member Author

@aG0aep6G @9il fixed

@dlang-bot
Copy link
Contributor

Fix Bugzilla Description
15995 std.conv.text and friends can be made faster with std.array.appender

@JackStouffer
Copy link
Member Author

Can someone add the "blocked" tag to this?

@schveiguy
Copy link
Member

One heuristic optimization -- until an argument produces some actual string output, there's no need to fire up an appender. Essentially, you have the single-argument case, no need to copy the string that was just generated and throw that string away. Not sure if it helps or hurts the performance.

@schveiguy
Copy link
Member

See my comment here: #4460 (comment)

@JackStouffer
Copy link
Member Author

Can someone kick the auto-tester?

auto app = appender!S();

foreach (arg; args)
app.put(to!S(arg));
Copy link
Member

@9il 9il Jul 10, 2016

Choose a reason for hiding this comment

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

app.formatValue(fmt, arg); should be used instead.

@9il
Copy link
Member

9il commented Jul 10, 2016

You can add trusted, but please use formatValue instead

@JackStouffer
Copy link
Member Author

You can add trusted

What if one of the arguments has a memory unsafe toString?

@JackStouffer JackStouffer force-pushed the textImpl branch 2 times, most recently from d03ad1a to 3927e7e Compare July 10, 2016 21:19
@JackStouffer
Copy link
Member Author

Ready to go

@9il
Copy link
Member

9il commented Jul 11, 2016

You can add trusted
What if one of the arguments has a memory unsafe toString?

Implementations should not be aware of what kind of toString is used, if they have both.

@9il
Copy link
Member

9il commented Jul 11, 2016

Is current implementation always @safe?

@JackStouffer
Copy link
Member Author

Is current implementation always @safe?

Depends on the implementation of to used for each of the arguments.

@JackStouffer
Copy link
Member Author

formatValue is also impure, so that's a no go

@JackStouffer
Copy link
Member Author

Ping @schveiguy @DmitryOlshansky @9il

@DmitryOlshansky
Copy link
Member

LGTM

@schveiguy
Copy link
Member

Auto-merge toggled on

@schveiguy
Copy link
Member

I'd like to have seen an attempt to avoid appender until necessary, but OK.

@schveiguy schveiguy merged commit c9df29e into dlang:master Jul 14, 2016
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.

6 participants