相关疑难解决方法(0)

C++比C#快多少?

或者它现在反过来了?

从我所听到的有些领域,C#证明比C++更快,但我从来没有勇气自己测试它.

你们中的任何一个人都可以详细解释这些差异,或者将我指向正确的地方以获取相关信息.

c# c++ performance benchmarking

230
推荐指数
17
解决办法
15万
查看次数

如何摆脱边界检查

有没有办法删除数组边界检查C#

这是我想要实现的目标:

public static int F(int[] M, int i) 
{
    return M[i]; // I can guarantee that [i] will never be outside of [0, M.Length]
}
Run Code Online (Sandbox Code Playgroud)

在这个函数调用之前,我有一个逻辑已经检查了边界(其中有一些额外的逻辑)。我要删除的内容如下:

Program.F(Int32[], Int32)
    L0000: sub rsp, 0x28
    L0004: cmp edx, [rcx+8]           ; I don't need this line
    L0007: jae short L0015            ; I don't need this line
    L0009: movsxd rax, edx
    L000c: mov eax, [rcx+rax*4+0x10]
    L0010: add rsp, 0x28
    L0014: ret
    L0015: call 0x00007ffc8877bc70    ; I don't need this line
    L001a: int3 …
Run Code Online (Sandbox Code Playgroud)

c# arrays assembly x86-64

9
推荐指数
1
解决办法
2708
查看次数

为什么添加额外的检查循环会对某些机器产生很大的影响,而对其他机器的差异很小?

我一直在做一些测试,看看在循环中检查有多大区别.这是通过考虑访问数组时由C#,Java等语言插入的隐式边界检查的成本而引起的.

更新:我已经在几台额外的计算机上尝试了相同的可执行程序,这会使正在发生的事情变得更加清晰.我首先列出了原始计算机,其次是我的现代笔记本电脑.在我的现代笔记本电脑上,在循环中添加额外的检查只会增加1到4%的时间,相比之下原始硬件的3到30%.

Processor   x86 Family 6 Model 30 Stepping 5 GenuineIntel ~2793 Mhz
Ratio 2 checks : 1 check = 1.0310
Ratio 3 checks : 1 check = 1.2769

Processor   Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz, 2301 Mhz, 4 Core(s), 8 Logical Processor(s)
Ratio 2 checks : 1 check = 1.0090
Ratio 3 checks : 1 check = 1.0393

Processor   Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz, 4 Cores(s)
Ratio 2 checks : 1 check = 1.0035
Ratio 3 checks : …
Run Code Online (Sandbox Code Playgroud)

c c++

6
推荐指数
1
解决办法
775
查看次数

阵列边界检查CLR中的消除?

我最近阅读了Dave Detlefs撰写的这篇文章,其中他介绍了一些CLR执行数组边界检查消除的情况.我决定自己测试一下,所以我做了以下几点:

  • 打开Visual Studio 2010 Ultimate SP1
  • 创建了一个类型为Console Application的新C#项目(默认情况下以.NET 4 Client Profile为目标)
  • 添加了以下代码(所有子方法都直接来自文章):

    class Program {
        static void Main(string[] args) {
            int[] array = new int[30];
            Test_SimpleAscend(array);
            Test_SimpleRedundant(array, 3);
    
            foreach (int i in array) {
                Console.WriteLine(i);
            }
        }
    
        static void Test_SimpleAscend(int[] a) {
            for (int i = 0; i < a.Length; i++)
                a[i] = i;
        }
    
        static void Test_SimpleRedundant(int[] a, int i) {
            int k = a[i];
            k = k + a[i];
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 切换到发布模式; 验证在Build选项中选中了"Optimize Code"

  • 为每个阵列访问添加了一个断点,开始调试(F5)并打开Dissassembly窗口 …

c# arrays clr optimization bounds-check-elimination

5
推荐指数
1
解决办法
4163
查看次数

如何消除此循环向量化的数组绑定检查?

我有一项任务是从二进制文字0x0上的数据库表中拆分多行varbinary(8000)列.但是,这可能会改变,所以我想保留这个变量.我想使用SQLCLR作为流表值函数快速执行此操作.我知道我的字符串总是至少有几千字节.

编辑:我已经更新了我的算法.为了避免内环展开的肮脏.但很难说服CLR对寄存器分配做出正确的选择.如果有一个简单的方法来说服CLR j和我真的是同一件事,那将是非常棒的.但相反,它确实是愚蠢的事情.优化第一个路径循环会很不错.但你不能使用goto进入循环.

我决定改编C函数memchr的64位实现.基本上不是一次扫描一个字节并进行比较,而是使用一些比特来一次扫描8个字节.作为参考,Array.IndexOf<Byte>对于一个答案执行与4字节扫描类似的操作,我只想继续这样做.有几点需要注意:

  1. 内存压力是SQLCLR功能中的一个非常现实的问题.String.Split因为它预先分配了很多我真正想避免的内存.它也适用于UCS-2字符串,这需要我将我的ascii字符串转换为unicode字符串,因此在返回时将我的数据视为lob数据类型.(SqlChars/ SqlString在转换为lob类型之前只能返回4000个字节).

  2. 我想流.避免String.Split它的另一个原因是同时完成其工作,造成大量内存压力.在具有大量分隔符的代码上,纯T-SQL方法将开始击败它.

  3. 我想保持它"安全".所以都管理好了.在安全检查中似乎有很大的惩罚.

Buffer.BlockCopy真的很快,而且比不断支付BitConverter的成本似乎更好地支付前一次成本.这仍然比将我的输入转换为字符串并保持该引用更便宜.

代码非常快,但似乎我在初始循环和关键部分支付了相当多的绑定检查,当我找到匹配时.作为具有大量分隔符的代码的结果,我倾向于输入一个更简单的C#枚举器,它只进行字节比较.

这是我的代码,

class SplitBytesEnumeratorA : IEnumerator
{
    // Fields
    private readonly byte[] _bytes;
    private readonly ulong[] _longs;
    private readonly ulong _comparer;
    private readonly Record _record = new Record();
    private int _start;
    private readonly int _length;

    // Methods
    internal SplitBytesEnumeratorA(byte[] bytes, byte delimiter)
    {
        this._bytes = bytes;
        this._length = bytes.Length;
        // we do this so that we can avoid a spillover scan …
Run Code Online (Sandbox Code Playgroud)

c# arrays clr performance sqlclr

5
推荐指数
1
解决办法
502
查看次数

如何使用移位运算符将字节舍入为0或255

为了在我的C#项目中重新映射位图图像中的像素,我想将RGB值四舍五入到255或者降到0;

每个值都是一个字节.

现在我正在做以下事情:

(byte)(Pixels[i] < 128 ? 0 : 255);
Run Code Online (Sandbox Code Playgroud)

我相信这可以通过快速方式实现,并且无需使用按位操作进行类型转换.我该怎么做呢?

c# bit-manipulation rounding

3
推荐指数
2
解决办法
475
查看次数