使用数学或字符串转换和.Substring()对数字进行子串

时间:2016-11-02 08:32:18

标签: c# performance numbers substring

我即将通过这些计算,所以我认为嘿为什么我只是不使用子串,然后我再次想到它会变慢......

我记得一位来自大学的老师教一些基于delphy的旧图形引擎,告诉我们使用plus而不是乘法来尝试你的计算,因为与multiply实现相比它真的很慢。所以数学的本质应该很快,但是使用了这么多的乘法和除法......

所以我虽然来到这里并问你......

有些人在他的网络服务中使用整数作为日期时间,我想把它分成一个模型...... 正如我所说我想写.toString然后我虽然它可能很慢,所以我虽然我会先搜索,看到没有想到你问我,但后来我意识到我必须写它之前我可以问问题...

所以这里是示例代码:

StartDate = Pc.ToDateTime(
    value/10000,
    (value - (value/10000)*10000)/100,
    value - ((value/10000)*10000) - (((value - (value/10000)*10000)/100)*100),
    0,
    0,
    0,
    0
);

Pc.ToDateTime(
    Convert.ToInt32(value.ToString().SubString(0,4)),
    Convert.ToInt32(value.ToString().SubString(4,2)),
    Convert.ToInt32(value.ToString().SubString(6,2)),
    0,
    0,
    0,
    0
);

修改 Pc => private static readonly PersianCalendar Pc = new PersianCalendar();

编辑2

AS @Yeldar Kurmangaliyev说,我把我的第一个代码改为:

StartDate = Pc.ToDateTime(
    value/10000,
    value%10000/100,
    value%100,
    0,
    0,
    0,
    0
);

编辑3

正如你所说,我用一种方法衡量我的自我表现。 我在这里使用秒表:

&编辑4:我添加了Ivan Stoev示例代码:

    public ActionResult PerformanceMeasure()
    {
        PersianCalendar pc = new PersianCalendar();
        var first = 0L;
        var second = 0L;
        var third = 0L;
        var forth = 0L;

        var value = 13950812;
        Stopwatch sw = new Stopwatch();

        sw.Reset();
        sw.Start();
        pc.ToDateTime(
                value / 10000,
                (value - (value / 10000) * 10000) / 100,
                value - ((value / 10000) * 10000) - (((value - (value / 10000) * 10000) / 100) * 100),
                0,
                0,
                0,
                0
            );
        sw.Stop();
        first = sw.ElapsedTicks;
        sw.Reset();


        sw.Reset();
        sw.Start();
        pc.ToDateTime(
                value / 10000,
                value % 10000 / 100,
                value % 100,
                0,
                0,
                0,
                0
            );
        sw.Stop();
        second = sw.ElapsedTicks;
        sw.Reset();


        sw.Reset();
        sw.Start();
        pc.ToDateTime(
                Convert.ToInt32(value.ToString().Substring(0, 4)),
                Convert.ToInt32(value.ToString().Substring(4, 2)),
                Convert.ToInt32(value.ToString().Substring(6, 2)),
                0,
                0,
                0,
                0
            );
        sw.Stop();
        third = sw.ElapsedTicks;
        sw.Reset();


        sw.Reset();
        sw.Start();
        int month, day;
        int year = Math.DivRem(Math.DivRem(value, 100, out day), 100, out month);
        pc.ToDateTime(
            year,
            month,
            day,
            0,
            0,
            0,
            0);
        sw.Stop();
        forth = sw.ElapsedTicks;
        sw.Reset();

        var ms = new { First = first, Second = second, Third = third, Forth = forth };

        return Json(ms, JsonRequestBehavior.AllowGet);
    }

以下是结果,多次运行

RUN 1:{"First":70,"Second":41,"Third":52,"Forth":42}
RUN 2:{"First":64,"Second":37,"Third":44,"Forth":37}
RUN 3:{"First":81,"Second":45,"Third":70,"Forth":47}
RUN 4:{"First":63,"Second":37,"Third":44,"Forth":38}
RUN 5:{"First":68,"Second":37,"Third":45,"Forth":37}
RUN 6:{"First":65,"Second":37,"Third":46,"Forth":38}
RUN 7:{"First":76,"Second":41,"Third":51,"Forth":41}
RUN 8:{"First":62,"Second":37,"Third":47,"Forth":37}
RUN 9:{"First":57,"Second":37,"Third":45,"Forth":37}
RUN 0:{"First":62,"Second":37,"Third":45,"Forth":38}

让我补充一点,当我更紧密,更快地运行它时,就像我开始复制粘贴每次运行到这里,有些时候第四次更快第二次,但不是所有时间,似乎一旦进行计算,那将缓存一小部分时间。顺便说一句,差异并不是那么大。

2 个答案:

答案 0 :(得分:3)

忘记速度,从可理解性/维护的角度来看,你的方式都不是很有效。

你应该做的只是:

var myDate = DateTime.ParseExact(value.ToString(), "yyyyMMdd", CultureInfo.InvariantCulture);

不要过早地优化您的计划。这不太可能很快成为瓶颈。

答案 1 :(得分:1)

如果使用得当,数学总是比通过从值到字符串和字符串到其他值的双重转换更好。

不要复制计算。使用局部变量存储中间结果。特别是涉及分裂和模数的计算。

在具体案例中,IMO的最佳解决方案如下:

static DateTime ToDateTime(int value)
{
    int month, day;
    int year = Math.DivRem(Math.DivRem(value, 100, out day), 100, out month);
    return Pc.ToDateTime(year, month, day, 0, 0, 0, 0);
}