1

我正在使用 unsafe 和字符匹配指针进行测试,计算一个 200 字节数组,沿着 1 meg 长的 char 数组中的每个位置作为安全/不安全/dll 调用速度比较的实验。

它们在发布模式下运行,优化代码,允许不安全,无边界检查。长字符数组专门用于最小化调用开销影响。

我得到的时间是

常规 560 毫秒

不安全的 830 毫秒

dll 205 毫秒

为什么不安全的速度较慢?

    byte[] buffer = new Byte[1000000];
    byte[] check = new Byte[1000];
    [DllImport("sortitdev.dll", CallingConvention=CallingConvention.StdCall)]
  //[DllImport("sortitfast.dll", CallingConvention=CallingConvention.StdCall)]      
  //[DllImport("sortitpellas.dll", CallingConvention=CallingConvention.StdCall)]        
    
    public unsafe static extern void sortitt([MarshalAs(UnmanagedType.LPArray)] byte[] buffer);
    
    public MainForm()
    {
        InitializeComponent();
    }
    
    void Button1Click(object sender, EventArgs e)  // do char array matching
    {
        byte match;
        Random rnd = new Random();
        for(int i=0;i<1000000;i++)
            buffer[i]=(byte)rnd.Next(0,256);
        for(int i=0;i<200;i++)
            check[i]=(byte)rnd.Next(0,256);
        Stopwatch sw = Stopwatch.StartNew();
        int kk=0;
        int jq=0;
        while(kk<999000)
        {
            kk++;
            match=0;
            for(jq=0;jq<199;jq++)
                if(buffer[kk+jq]==check[jq])match++;
            buffer[kk]=match;
        }
        sw.Stop();
        textBox1.Text= sw.Elapsed.TotalMilliseconds.ToString();
        sw.Reset();
        sw.Start();
        unsafe
        {
            fixed (byte* bufptr=&buffer[0] , chckptr=&check[0])
            {
                byte* bufptrC=bufptr;  // modifiable pointer
                byte* chckptrC=chckptr;
                byte* bufhldptr;
                byte* chckhldptr;
                int k=999000;
                int jw=0;
                while(k>0)
                {
                    bufhldptr=bufptrC;
                    match=0;
                    chckhldptr=chckptrC;
                    for(jw=0;jw<199;jw++)
                        if(*bufhldptr++==*chckhldptr++)match++;
                    *bufptrC++=match;
                    k--;
                }
            }
            sw.Stop();
            textBox2.Text= sw.Elapsed.TotalMilliseconds.ToString();
        }
        sw.Reset();
        for(int tt=0;tt<200;tt++) buffer[tt]=(byte)tt;
        
        sw.Start();
        unsafe
        {
            fixed(byte* dadata=&buffer[0])
            {
                sortitt(buffer);
            }
        }
        sw.Stop();
        textBox3.Text= sw.Elapsed.TotalMilliseconds.ToString();
        int kll=(int)buffer[1];
        textBox4.Text= kll.ToString();
    }
}
4

1 回答 1

0

我检查了您的代码,但没有发现您的不安全代码速度较慢。但是,我重新编写了您的不安全代码(相当快 - 仔细检查),但我相信这对您来说应该更简单:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    byte[] buffer = new byte[1000000];
    byte[] check = new byte[200];

    private unsafe void button1_Click(object sender, EventArgs e)  // do char array matching
    {
        Random rnd = new Random();
        rnd.NextBytes(buffer);
        rnd.NextBytes(check);
        Stopwatch sw = Stopwatch.StartNew();

        byte match = 0;
        int kk = 0;
        int jq = 0;

        while (kk < 999000)
        {
            kk++;
            match = 0;
            for (jq = 0; jq < 199; jq++)
                if (buffer[kk + jq] == check[jq])
                    match++;
            buffer[kk] = match;
        }

        sw.Stop();
        textBox1.Text = sw.Elapsed.TotalMilliseconds.ToString();
        sw.Reset();
        sw.Start();

        fixed (byte* pCheck = check, pBuffer = buffer)
        {
            match = 0;
            kk = 0;
            jq = 0;

            while (kk < 999000)
            {
                kk++;
                match = 0;
                for (jq = 0; jq < 199; jq++)
                    if (pBuffer[kk + jq] == pCheck[jq])
                        match++;
                pBuffer[kk] = match;
            }
        }
        sw.Stop();
        textBox2.Text = sw.Elapsed.TotalMilliseconds.ToString();
    }
}

结果:

托管:404 毫秒不安全:284 毫秒

这是通过右键单击项目并在没有调试器的情况下启动新实例在发布中执行的。我还检查了我的代码,两种方法都给出了相同的结果。

于 2013-05-24T18:46:50.657 回答