我试图衡量在访问值类型和引用类型列表时使用a for
和a 的区别foreach
.
我使用以下类进行分析.
public static class Benchmarker
{
public static void Profile(string description, int iterations, Action func)
{
Console.Write(description);
// Warm up
func();
Stopwatch watch = new Stopwatch();
// Clean up
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
watch.Start();
for (int i = 0; i < iterations; i++)
{
func();
}
watch.Stop();
Console.WriteLine(" average time: {0} ms", watch.Elapsed.TotalMilliseconds / iterations);
}
}
Run Code Online (Sandbox Code Playgroud)
我用double
我的价值类型.我创建了这个'假类'来测试引用类型:
class DoubleWrapper
{
public double Value { get; set; }
public DoubleWrapper(double value)
{
Value …
Run Code Online (Sandbox Code Playgroud) 考虑以下功能:
public static bool TryToDoStuff(ReadOnlySpan<byte> input, Span<byte> destination) {
...
}
Run Code Online (Sandbox Code Playgroud)
这个函数返回它是否能在"做的东西" destination
基础上input
的内容.
我想检查内存区域是否"包裹" input
并destination
相交,如果是,则抛出异常,因为这会破坏input
数据.我怎么能这样做(没有反射或不安全的代码)?
我知道我可以编写一些xmldoc并警告用户参数不应该相交,但这是一个穷人的解决方案.
编辑:对于那些要求举例的人,Wazner的例子非常重要.
// On arrays
Span<byte> firstArray = new byte[10];
Span<byte> secondArray = new byte[10];
Intersects<byte>(firstArray.Slice(5, 5), firstArray.Slice(3, 5)); // Should throw
Intersects<byte>(firstArray.Slice(5, 5), secondArray.Slice(3, 5)); // Should not throw
// And on stackallocated memory
Span<byte> firstStack = stackalloc byte[10];
Span<byte> secondStack = stackalloc byte[10];
Intersects<byte>(firstStack.Slice(5, 5), firstStack.Slice(3, 5)); // Should throw
Intersects<byte>(firstStack.Slice(5, 5), secondStack.Slice(3, …
Run Code Online (Sandbox Code Playgroud) 我是xUnit的新手,但据我所知,检查是否抛出异常的标准方法是使用Assert.Throws<T>
或Assert.ThrowsAny<T>
方法.
但是这些方法期望将Action作为参数; 并且ref结构不能"嵌入"lambda中.
那么,如何测试ref struct的给定方法是否抛出?不起作用的代码示例:
[Fact]
public void HelpMe() {
var pls = new Span<byte>();
Assert.ThrowsAny<Exception>(() => {
plsExplode = pls[-1];
});
}
Run Code Online (Sandbox Code Playgroud) 我习惯于检查方法的参数是否为null(然后继续抛出异常),我几乎不再考虑它了.如果参数是引用类型,那么它就在那里:
if(arg == null)
throw new ArgumentNullException(nameof(arg));
Run Code Online (Sandbox Code Playgroud)
但是,如果我要立即使用arg怎么办?我应该检查一下吗?我的意思是,如果我不这样做,无论如何,envinroment将为我抛出(NullReferenceException).
例如:
public int DoStuff(object o)
{
return o.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
我可以轻松地添加null检查:
public int DoStuff(object o)
{
if(o == null)
throw new ArgumentNullException(nameof(o));
return o.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下都会抛出异常(在几乎完全相同的行中,出于调试目的).唯一的区别是类型.
问题:在具有单个引用类型参数的公共方法上,如果我要立即使用该参数,我是否仍应检查它是否是?null
我正在尝试实现一个tcp'echo server'.简单的东西:
它工作得很好,所以我决定并行化服务器; 使它能够及时处理多个客户端.由于大多数Python解释器都有GIL,因此多线程不会削减它.我不得不使用多处理器......而男孩,这就是事情发生的原因.
我正在使用Windows 10 x64和WinPython适用于Python 3.5.2 x64.
我的想法是创建一个套接字,初始化它(绑定和监听),创建子进程并将套接字传递给子进程.但是对于我的爱...我无法做到这一点,我的子过程几乎立即死亡.最初我有一些问题'腌制'套接字......所以我google了一下,并认为这是问题.所以我尝试通过管道将多个处理队列传递给我的套接字,我的最后一次尝试是'forkpickling'并在处理创建过程中将其作为字节对象传递.什么都行不通.
有人可以在这里说清楚吗?告诉我出了什么事? 也许整个想法(共享套接字)是坏的...如果是这样,请告诉我如何实现我的初始目标:使我的服务器能够立即处理多个客户端(在Windows上)(不要告诉我有关线程的信息) ,我们都知道python的线程不会削减它¬¬)
还值得注意的是,调试功能不会创建任何文件.我相信没有任何过程可以长时间运行它.
我的服务器代码的典型输出是(只有运行之间的差异是进程号):
Server is running...
Degree of parallelism: 4
Socket created.
Socket bount to: ('', 0)
Process 3604 is alive: True
Process 5188 is alive: True
Process 6800 is alive: True
Process 2844 is alive: True
Press ctrl+c to kill all processes.
Process 3604 is alive: False
Process 3604 exit code: 1
Process 5188 is alive: False
Process 5188 exit code: …
Run Code Online (Sandbox Code Playgroud) 我刚刚在我的一个类中创建了以下方法
public static bool Assimilate(this List<Card> first, List<Card> second)
{
// Trivial
if (first.Count == 0 || second.Count == 0)
{
return false;
}
// Sort the lists, so I can do a binarySearch
first.Sort();
second.Sort();
// Copia only the new elements
int index;
for (int i = 0; i < second.Count; i++)
{
index = first.BinarySearch(second[i]);
if (index < 0)
{
first.Insert(~index, second[i]);
}
}
// Edit
second = null;
return true;
}
Run Code Online (Sandbox Code Playgroud)
我的一个朋友,审查我的代码,说我不应该创建'扩展List类'的方法,因为这违反了开放/封闭原则.如果我想扩展类List,我应该创建一个继承自List的新类,并在该新类中实现我的"merge"方法.他是对的吗?扩展List类违反了开放/封闭原则?
System.Drawing.Point
GetHashCode
如果你打算用它来描述图像/位图中的"像素",它有一个非常非常糟糕的方法:它只是X和Y坐标之间的XOR.
因此,对于具有2000x2000大小的图像,它具有荒谬的分数,因为只有对角线中的数字才具有相当好的散列.
GetHashCode
正如一些人已经在这里提到的那样,使用未经检查的乘法创建一个合适的方法非常容易.
但是我可以做些什么来使用这种改进的GetHashCode
方法HashSet
呢?我知道我可以创建自己的类/结构MyPoint
并使用这种改进的方法实现它,但是我会破坏我的项目中使用的所有其他代码片段System.Drawing.Point
.
是否可以System.Drawing.Point
使用某种扩展方法等"覆盖"该方法?或者"告诉" HashSet
使用另一个功能而不是GetHashCode
?
目前我正在使用SortedSet<System.Drawing.Point>
带有自定义IComparer<Point>
来存储我的积分.当我想知道该集是否包含Point I调用时BinarySearch
.它比HashSet<System.Drawing.Point>.Contains
具有10000个聚合的集合中的方法更快,但它没有像HashSet
好的哈希一样快.
在推动人们投票结束这个问题之前,请您检查一下最小的可复制示例吗?
这个问题已经被问了一千遍了,但是这次确实没有任何意义。
我收到以下异常消息:
System.ArgumentException
HResult=0x80070057
Message=Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: 'Minotaur.GeneticAlgorithms.LexicographicalFitnessComparer'.
Source=System.Private.CoreLib
StackTrace:
at System.Collections.Generic.IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(Object comparer)
at System.Collections.Generic.ArraySortHelper`2.Sort(TKey[] keys, TValue[] values, Int32 index, Int32 length, IComparer`1 comparer)
at System.Array.Sort[TKey,TValue](TKey[] keys, TValue[] items, IComparer`1 comparer)
at Minotaur.FitnessReportMaker.MakeReport(Array`1 fitnesses) in C:\Source\minotaur\Minotaur\Minotaur\FitnessReportMaker.cs:line 18
at Minotaur.Theseus.EvolutionEngine.Run(IEnumerable`1 initialPopulation) in C:\Source\minotaur\Minotaur\Minotaur\Theseus\EvolutionEngine.cs:line 63
at Minotaur.Program.Run(ProgramSettings settings) in C:\Source\minotaur\Minotaur\Minotaur\Program.cs:line 148
at …
Run Code Online (Sandbox Code Playgroud) 不要重复自己或封装?
假设我创建了以下内容:
我想让Marker实现IMask接口.但是后来我会重复自己(最后查看代码)或者我可以在Marker公开中找到我的位置.但接下来我将揭露我班级的实施情况.或者我可以从Spot继承Spot,但这不是理想的解决方案,因为在语义上Marker不是特定类型的Spot.
如果我创建另一个将Spot作为字段并且我又想要实现IMask接口的类呢?我会再次重复自己.那么,我该怎么办?我应该在Spot中公开列表吗?然后将Spot in Marker公之于众?或者我应该重复这些电话?
interface IMask : IList<Point>
{
public void MoveTo(Point newCenter);
// ... other Methods
}
public class Spot : IMask
{
List<Point> points;
public void DoSpotyStuff()
{
// blabla
}
// Other methods
// ...
// Finally the implementation of IMask
public void MoveTo(Point newCenter)
{
// blabla
}
// And of course the IList methods
public void Add(Point newPoint)
{
points.Add(newPoint);
}
}
public class Marker : IMask
{ …
Run Code Online (Sandbox Code Playgroud) 我知道这是错误的(尝试以 C/C++ 思维方式使用 C# 进行编码)。但是是否可以在 C# 中创建内联函数/内联递归函数(直到第 N 次调用)/宏?
因为如果我打算调用同一个函数 1000 次,但它是一个简单的函数,那么创建堆栈的开销是相当大的......而且是不必要的。
在 C 中我可以使用内联函数。C#中有类似的东西吗?
再说一次...我并不是说 C/C++ 更好...我只是 C# 新手,没有人问这些简单的问题...
问题:当我的节目明星我创建一个List<myClass> myList
并用对象填充它.这些对象是使用文件中的日期创建的.之后,我不想更改该列表,也不想再次访问这些文件.但我需要在很多类/方法中访问该List
我提出的解决方案:List<myClass> myList
在静态类中创建私有,并使用我的静态类的构造函数填充它,并仅使用返回myList.AsReadOnly()的属性访问它.这样我就无法改变实际的清单.但是AsReadOnly的回归是一个IList,对吧?我在MSDN上检查IList并且没有BinarySearch方法......这会使整个事情变得非常缓慢.
我该如何解决这个问题?复制IList返回正常列表,以便我可以排序和BinarySearch吗?或者可能更改整个"myList.AsReadOnly()"方法?我愿意接受各种建议和方法^^改变整个代码不是问题.
编辑:
c# ×11
list ×2
performance ×2
.net-core ×1
32bit-64bit ×1
exception ×1
function ×1
gdi+ ×1
gethashcode ×1
inheritance ×1
inline ×1
interface ×1
macros ×1
networking ×1
python ×1
readonly ×1
ref-struct ×1
sockets ×1
sorting ×1
windows ×1
xunit ×1