Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 最快的方法使剩余计数达到C中的下一个上限10#_C#_Performance_Optimization - Fatal编程技术网

C# 最快的方法使剩余计数达到C中的下一个上限10#

C# 最快的方法使剩余计数达到C中的下一个上限10#,c#,performance,optimization,C#,Performance,Optimization,我在一组非常大的数字中做一个运算(每个数字的长度为13位) 我需要用校验和验证每个数字。校验和数字将显示数字到下一个十的距离,即: checksum checksum digit 20 0 21 9 22 8 33 7 34 6 35

我在一组非常大的数字中做一个运算(每个数字的长度为13位)

我需要用校验和验证每个数字。校验和数字将显示数字到下一个十的距离,即:

checksum    checksum digit
      20                 0
      21                 9
      22                 8
      33                 7
      34                 6
      35                 5
      36                 4
      37                 3
     208                 2
       9                 1
数字为EAN-13格式。因此,最大数字总和=217(99999999999:无校验和验证)

到目前为止,我认为最快的方法是将数据预加载到int数组中并通过索引检索它

这是最快的方式吗

或者在这一点上,这不再重要了,因为它的执行速度足够快,甚至可以达到很多数字

更新: 如前所述,将cheksum的校验和数字值预加载到数组中:

for (int i = 0; i < 220; i += 10)
{
    matchValues[i] = 0;
    matchValues[i + 1] = 9;
    matchValues[i + 2] = 8;
    matchValues[i + 3] = 7;
    matchValues[i + 4] = 6;
    matchValues[i + 5] = 5;
    matchValues[i + 6] = 4;
    matchValues[i + 7] = 3;
    matchValues[i + 8] = 2;
    matchValues[i + 9] = 1;
}
for(int i=0;i<220;i+=10)
{
匹配值[i]=0;
匹配值[i+1]=9;
匹配值[i+2]=8;
匹配值[i+3]=7;
匹配值[i+4]=6;
匹配值[i+5]=5;
匹配值[i+6]=4;
匹配值[i+7]=3;
匹配值[i+8]=2;
匹配值[i+9]=1;
}
有了它,我就可以用匹配的校验和数字
matchValues[sum]覆盖所有校验和

所以:
匹配值[208]=2
匹配值[9]=1

等等。

您可以使用模来计算到天花板的距离。显然,您仍然需要迭代每个数字

int modulo = i % 10;
int distanceFromTen = modulo == 0 ? 0 : 10 - modulus;
另一个解决方案是
intdistancefromten=(int)(数学上限(i/10d)*10-i)

我已经为这两种方法运行了基准测试:

private static void Main(string[] args)
{
    //Console.WriteLine("Checking {0}", i);

    int loops = 10;

    long averageModulo = 0;
    long averageCeiling = 0;

    for (int l = 0; l < loops; l++)
    {

        Stopwatch sw = new Stopwatch();

        sw.Start();
        for (int i = 0; i < 10000000; i++)
        {
            int modulus = i % 10;
            int distanceFromTen = modulus == 0 ? 0 : 10 - modulus;
        }
        sw.Stop();


        Stopwatch swTwo = new Stopwatch();

        swTwo.Start();

        for (int i = 0; i < 10000000; i++)
        {
            int distanceFromTenTwo = (int)(Math.Ceiling(i / 10d) * 10 - i);
        }

        swTwo.Stop();

        Console.WriteLine("Modulo:       {0} ({1}ms)", sw.ElapsedTicks, sw.ElapsedMilliseconds);

        averageModulo += sw.ElapsedTicks;

        Console.WriteLine("Math.Ceiling: {0} ({1}ms)", swTwo.ElapsedTicks, swTwo.ElapsedMilliseconds);

        averageCeiling += swTwo.ElapsedTicks;

        Console.WriteLine("");
    }

    Console.WriteLine("Average modulo:  {0}", averageModulo / loops);
    Console.WriteLine("Average ceiling: {0}", averageCeiling / loops);

    Console.ReadLine();
}
private static void Main(字符串[]args)
{
//WriteLine(“检查{0}”,i);
int循环=10;
long averageModulo=0;
长期平均上限=0;
for(int l=0;l
模运算总是比上限快(可能是因为装箱)。尽管如此,这两项行动都非常迅速


有了新的编辑,我认为现在的目标是在尽可能短的时间内生成有效的EAN。下面是一些代码,它将在3.5秒内生成100000000个EAN-13校验和(如维基百科页面上记录的)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

internal class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine("");

        long start = 0;
        long end = 99999999;

        long count = end - start + 1;
        long[] eans = new long[count];

        Stopwatch sw = new Stopwatch();

        sw.Start();

        Parallel.For(start, end + 1, i => {
            eans[i] = GenerateEAN13(i);
        });

        sw.Stop();

        Console.WriteLine("Generation of {0} EAN-13s took {1} ticks ({2} ms)", count, sw.ElapsedTicks, sw.ElapsedMilliseconds);

        Console.ReadLine();
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static long GenerateEAN13(long number)
    {
        long checksum = 0;
        long digit = 0;
        long tmp = number;

        for (int i = 13; i >= 0; i--)
        {
            digit = tmp % 10;
            tmp = tmp / 10;

            checksum += i % 2 == 0 ? digit * 3 : digit;

            if (tmp < 10)
                break;
        }

        long modulus = checksum % 10;
        checksum = modulus == 0 ? 0 : 10 - modulus;

        return number * 10 + checksum;
    }
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.IO;
Net系统;
使用System.Net.Sockets;
使用系统数字;
使用System.Runtime.CompilerServices;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
内部课程计划
{
私有静态void Main(字符串[]args)
{
控制台。写线(“”);
长启动=0;
长端=9999999;
长计数=结束-开始+1;
long[]eans=新的long[count];
秒表sw=新秒表();
sw.Start();
Parallel.For(开始、结束+1,i=>{
eans[i]=第13(i)代;
});
sw.Stop();
WriteLine(“生成{0}EAN-13s需要{1}个滴答({2}ms)”,count,sw.elapseddicks,sw.elapseddicks);
Console.ReadLine();
}
[MethodImpl(MethodImplOptions.AggressiveInline)]
公共静态长生成器AN13(长编号)
{
长校验和=0;
长数字=0;
长tmp=数量;
对于(int i=13;i>=0;i--)
{
数字=tmp%10;
tmp=tmp/10;
校验和+=i%2==0?位数*3:位数;
如果(tmp<10)
打破
}
长模数=校验和%10;
校验和=模==0?0:10-模;
返回编号*10+校验和;
}
}

您可以使用模来计算到天花板的距离。显然,您仍然需要迭代每个数字

int modulo = i % 10;
int distanceFromTen = modulo == 0 ? 0 : 10 - modulus;
另一个解决方案是
intdistancefromten=(int)(数学上限(i/10d)*10-i)

我已经为这两种方法运行了基准测试:

private static void Main(string[] args)
{
    //Console.WriteLine("Checking {0}", i);

    int loops = 10;

    long averageModulo = 0;
    long averageCeiling = 0;

    for (int l = 0; l < loops; l++)
    {

        Stopwatch sw = new Stopwatch();

        sw.Start();
        for (int i = 0; i < 10000000; i++)
        {
            int modulus = i % 10;
            int distanceFromTen = modulus == 0 ? 0 : 10 - modulus;
        }
        sw.Stop();


        Stopwatch swTwo = new Stopwatch();

        swTwo.Start();

        for (int i = 0; i < 10000000; i++)
        {
            int distanceFromTenTwo = (int)(Math.Ceiling(i / 10d) * 10 - i);
        }

        swTwo.Stop();

        Console.WriteLine("Modulo:       {0} ({1}ms)", sw.ElapsedTicks, sw.ElapsedMilliseconds);

        averageModulo += sw.ElapsedTicks;

        Console.WriteLine("Math.Ceiling: {0} ({1}ms)", swTwo.ElapsedTicks, swTwo.ElapsedMilliseconds);

        averageCeiling += swTwo.ElapsedTicks;

        Console.WriteLine("");
    }

    Console.WriteLine("Average modulo:  {0}", averageModulo / loops);
    Console.WriteLine("Average ceiling: {0}", averageCeiling / loops);

    Console.ReadLine();
}
private static void Main(字符串[]args)
{
//WriteLine(“检查{0}”,i);
int循环=10;
long averageModulo=0;
长期平均上限=0;
for(int l=0;l
模运算总是更快