我用String.StartsWith遇到了一个奇怪的性能"工件".
使用OrdinalIgnoreCase的String.StartsWith似乎比使用String.StartsWith更快,而没有指定StringComparison.(快2-4倍)
但是,使用没有StringComparison的String.Equals比使用OrdinalIgnoreCase时更快地检查相等性.(虽然速度大致相同)
问题是为什么?为什么他们在这两种情况下表现不同?
这是我使用的代码:
public static void Test()
{
var options = new[] { "asd/klfe", "qer/jlkfe", "p33/ji", "fkjlfe", "asd/23", "bleash", "quazim", "ujv/3", "jvd/kfl" };
Random r;
const int trialSize = 100000;
const int trials = 1000;
Stopwatch swEqOp = new Stopwatch();
Stopwatch swEq = new Stopwatch();
Stopwatch swEqOrdinal = new Stopwatch();
Stopwatch swStartsWith = new Stopwatch();
Stopwatch swStartsWithOrdinal = new Stopwatch();
for (int i = 0; i < trials; i++)
{
{
r = new Random(1);
swEqOp.Start();
for (int …Run Code Online (Sandbox Code Playgroud) 在C#7.2中,readonly结构总是传递给函数,好像"in"参数存在一样?如果没有,在什么情况下复制内存是有用的,因为它是只读的?
我有一个readonly结构:
public readonly struct Vec2
{
public readonly double X;
public readonly double Y;
}
Run Code Online (Sandbox Code Playgroud)
因此,当调用数十亿次时,这两种方法之间会有性能差异:
public double Magnitude1(Vec2 v)
{
return Math.Sqrt(v.X*v.X + v.Y*v.Y);
}
public double Magnitude2(in Vec2 v)
{
return Math.Sqrt(v.X*v.X + v.Y*v.Y);
}
Run Code Online (Sandbox Code Playgroud)
如果是这样,为什么编译器不会认识到Vec2是一个只读结构而只是传递它就好像"in"存在一样?是否有一个实例,您可能希望在没有"in"修饰符的情况下传递只读结构?
考虑以下代码:
public unsafe struct MyStruct
{
public fixed int Nums[128];
}
private static void DoSomething()
{
MyStruct s = new MyStruct();
unsafe
{
int val = s.Nums[23];
Console.WriteLine(val.ToString()); //Is this guaranteed to be "0"?
}
}
Run Code Online (Sandbox Code Playgroud)
这样的话,是不是保证新建一个的时候MyStruct,at每个索引的值都Nums为0呢?
在我自己的测试中,它似乎确实被初始化为默认值,但我问是因为它是unsafe.
我有一个可以简化为以下问题陈述的问题:
给定一系列的双精度数,每个均在范围内
[0, 1e7],修改最后一个元素,以使数字的总和恰好等于目标数字。双精度数系列已加到epsilon(1e-7)内的目标数,但不是==。
下列代码有效,但是否可以保证满足第一句中所述要求的所有输入有效?
public static double[] FixIt(double[] input, double targetDouble)
{
var result = new double[input.Length];
if (input.Length == 0) return result;
double sum = 0;
for (int i = 0; i < input.Length - 1; i++)
{
sum += input[i];
result[i] = input[i];
}
double remainder = targetDouble - sum;
result[result.Length - 1] = remainder;
return result;
}
var arr1 = Enumerable.Repeat(Math.PI / 13, 13).ToArray();
var arr2 = FixIt(arr1, Math.PI);
Debug.Print(Math.PI.ToString("R")); //3.1415926535897931
Debug.Print(arr1.Sum().ToString("R")); //3.1415926535897922
Debug.Print(arr2.Sum().ToString("R")); //3.1415926535897931 …Run Code Online (Sandbox Code Playgroud) 我有(x,y,z)法线作为3个浮点数,我想将它们打包成VBO数组GL_INT_2_10_10_10_REVs,以减少显卡的内存消耗.谁能提供一个如何在C++/C#中做到这一点的例子?
OpenGL文档说你可以这样做 - https://www.opengl.org/wiki/Vertex_Specification_Best_Practices
但是,我找不到任何关于如何将三个浮点数(可以是正数或负数)放入单个压缩4字节结构的示例.
请注意,我知道 Debug.Print - Console.WriteLine 是我正在尝试做的事情的一个非常简化的示例。
有没有办法让一行代码只存在于调试模式中,而根本不会出现在 Release 中?
我有一些命令可以帮助我调试对性能至关重要的代码部分的执行,并且我在整个函数的关键位置放置了大量命令。
这是我所做的一个例子:
using System;
public class C {
public Object _obj = new object();
public void M()
{
Alpha("This goes away in Release");
Alpha(_obj.GetHashCode() + "...but this doesn't");
#if DEBUG
//But I don't want this three line deal.
Alpha(_obj.GetHashCode() + "...of course this does get removed");
#endif
}
public static void Alpha(String s)
{
#if DEBUG
Console.WriteLine(s);
#endif
}
}
Run Code Online (Sandbox Code Playgroud)
问题是在发布模式下,编译器识别出第一次调用在发布模式下什么都不做,然后将其删除。但它在第二次调用中没有这样做。我知道这是因为我在SharpLab进行了测试:https://sharplab.io/#v2:EYLgHgbALANALiAhgZwLYB8CQBXZBLAOwHMACAZQE9k4BTVAbgFgAoTAB22ABs8BjE3lxTISAYRIBvFpnace/APLAAVjV5wSAfQD2KkgF4SBGgHcSu1eoAUASiatZ3PiQBu2vABMSAWVslpmFIOmACCXGwAFohWAEQAKhF4IkTaNCKIJogUJIQkAEo0XDQoNDF2AaHhUVY6KgB0AOI0cAASKBGi2h40fgDUJDF1Q8DYGnCJIh6pyAQAAgC0AIxwZfYymBUAxHgAZiQAIgCiAEIAqg3+wZgA9NfHoyQAkiRTc0samQRjEyTjAE40GgkHjGF7FLh1CqVSLRWrKRrNNrIDpdHo2Ej9QZDbR7XjabB/ZBA8ZJF7TEhEZokAGobQuGgeVZbGgEDy7KEBAC+AQCHCc/GoiDgzjcnhIYRhVjIcD+hFIyBsASC622eyOZwaUM6BGQ2iKdQA6rLaAAZQg9BVrGSbFlsnZc6ScoA==
有没有办法避免三行版本?