Tag: 性能

Casting(int?)null与new int?() – 哪个更好?

当我将值加载到类和结构中时,我需要Nullable类型,当我需要它们可以为空时,例如从数据库加载可空值(如下例所示)。 考虑以下代码片段: public class InfoObject { public int? UserID { get; set; } } // Load the ID into an SqlInt32 SqlInt32 userID = reader.GetSqlInt32(reader.GetOrdinal(“intUserID”)); 当我需要将值加载到可空属性中时,有时我会这样做: infoObject.UserID = userID.IsNull ? (int?)null : userID.Value; 有时我这样做: infoObject.UserID = userID.IsNull ? new int?() : userID.Value; 虽然它们实现了相同的结果,但我想知道是否有人知道在(int?)null和new int?()之间使用哪个更好的性能,最小的IL代码,最佳实践等? 一般来说我一直偏爱上面代码的new int?()版本,但是我不确定对于编译器来说,cast (int?)null是否比new int?()更快。 干杯!

Console.WriteLine加快我的代码?

我一直在研究如何加速我的应用程序,因为它对性能至关重要……即每一毫秒我都可以摆脱它更好。 为此,我有一个调用其他方法的方法,其中每个方法都包含一个Stopwatch计时器和Console.WriteLine调用。 即: private void SomeMainMethod() { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); SomeMethod(); sw.Stop(); Console.WriteLine(“Time for SomeMethod = {0}ms”, sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); SomeOtherMethod(); sw.Stop(); Console.WriteLine(“Time for SomeOtherMethod= {0}ms”, sw.ElapsedMilliseconds); //… } 问题是每当我注释掉Stopwatch和Console.WriteLine行代码运行大约20ms(而不是50)慢,这是我需要的很多。 有人知道为什么吗? 编辑: SomeMainMethod方法和类中的其他方法也包含在类似于上面的Stopwatch和Console.WriteLine调用中。 SomeMainMethod及其调用的方法是类的一部分,该类是从控制台测试平台调用的类库的一部分,所有这些都是单线程的。 有关更多信息:该应用程序在x86 .NET 4.6.1发布模式下运行,并启用了优化。 我也在视觉工作室2013中运行它,而不是在它之外。

C#清除List ,值类型仍然是O(n)操作?

根据Microsoft 文档 ,在List上调用Clear()是O(n)操作。 我猜这是因为如果列表要保存引用,则需要将它们置空。 我想知道如果列表具有值类型,Clear()仍然是O(n)操作,因为容量没有改变。 复位索引指针和计数不应该足够吗? 我问这个是因为在当前的应用程序中我们使用的列表在很短的时间内就被清除了数十万次,并且想知道是否有不同的实现可以使它更快。

List .IndexOf()与List .FindIndex()的效率

其中一种方法 List.IndexOf()和 List.FindIndex() 在处理时间方面更有效? 此实例中的T类型为String 。

C#的任何等效“扩展”?

我正在研究我的Mandelbrot屏幕保护程序的新版本,并且我的浮点精确度已经不足了 – 简单的双值没有足够的重要数据来满足我的需求。 更重要的数字=更大程度的放大分形 回到我在Delphi 7中编写这个屏幕保护程序的版本时,我使用了80位大小的扩展浮点类型。 在.NET中,我可以切换到十进制 ,但是这对性能的影响非常糟糕,分形生成速度减慢了20倍左右。 是否有任何相当于.NET的扩展 ? 或者,是否有任何数字类型的精度高于double仍然使用FPU进行评估,因此不具有十进制的高性能命中? 更新 我的屏幕保护程序已经设法缩放许多(很多!)数量级的分形; 目前,只有当使用的数字类型无法分隔相邻像素的纵坐标时,它才会重置为基础分形。 从双倍扩展的改进中额外的16位精度将使我接近16倍的大小倍增。 至于性能,我的算法已经设法消除了所需数学的95-99%(与计算许多像素的简单实现相比),同时保留了分形的完整性。

使用GPU加速BigInteger计算

我几乎完成了一个处理一些非常大的整数的算法(大约2的数量增加到100,000,000的幂)。 这需要在16核服务器上使用几个小时的高度并行代码,并且内存足够,因为算法不是内存密集型的。 我使用.NET 4中的BigInteger类。 算法的细节并不重要,但对于上下文,以下是对这些整数执行的操作的非常详尽的列表以及算法的一些显着特征: 加法/减法。 大数乘以小数。 通过非常小的数字划分大数(例如2)。 基地2日志。 基地2力量。 两个或多个大数字的比较(最小/最大)。 没有任何关于素数的介入。 该算法专门设计为不占用大量内存,因为内存访问的性能损失超过了一些智能的即时计算。 然而,如果要改进内存访问,算法可以合理地受益。 我已经尽可能地优化了代码,现在分析只显示了两个瓶颈: 计算基数2记录如此大的数字。 检查这些数字中预定义的二进制数字模式。 这是因为访问BigInteger底层数据的唯一方法是首先使用ToByteArray而不是就地操作。 此外,在字节大小的块上操作也无助于提高性能。 考虑到内存访问和日志操作,我开始考虑GPU以及是否可以有效地卸载一些工作。 我对GPU知之甚少,只是它们针对浮点运算进行了优化。 我的问题是,使用像GPU .NET这样的库,如何在GPU上处理如此大的数字? 我可以以某种方式利用浮点优化来计算这么大的数字的Log吗? 寻找形成战略的起点。

使用ReceiveById可怕的MSMQ性能

每秒只有20条消息! 这就是我得到的! 这是从队列中查看50条消息并使用ReceiveById并行接收它们的代码。 队列中的消息总数是500.我也测试了其他数字。 但是上限是每秒20条消息! 我在某处完全不受影响吗? 编辑1: 1 – 我需要队列可以恢复。 但有趣的是,即使我将可恢复选项设置为false; 仍然是上限是20消息/秒。 2 – 我被迫在这里使用MSMQ,因为涉及一些遗留应用程序。 但是如果这个代码是正确的并且这个前20个限制确实存在,我可以说服该组切换。 因此,任何推荐(基于实际经验)替换MSMQ都是非常受欢迎的(请注意,如果出现任何类型的失败,我们需要保留我们的消息)。 3 – 我已经将ThreadPool中的线程数设置为高数,以防它有所帮助,但实际上在这段代码中它将导致创建100到200个线程。 我已经测试了从50到10000的不同数字,没有差异。 4 – 在每个任务中创建一个新的MessageQueue,因为ReceiveById不是线程安全的。 5 – 正如人们在代码中看到的那样,消息大小非常低; 它只是一个字符串加一个int。 编辑2:[ 非常奇怪的新结果 ] 我已经玩了这段代码的每一点,发现了这个:如果我注释掉行singleLocal.UseJournalQueue = false; 在我的任务中,我每秒最多可以读取1200条消息。 不令人印象深刻,但在我的情 奇怪的部分是UseJournalQueue的默认值为false; 为什么再次将其设置为false应该会在性能上产生这样的差异? static partial class Program { static void Main(string[] args) { ThreadPool.SetMaxThreads(15000, 30000); ThreadPool.SetMinThreads(10000, 20000); var qName = […]

迭代HashSet的最快/最安全的方法是什么?

我还是C#的新手,但是在特定情况下通过论坛发帖使用HashSet而不是List来注意到这些优势。 我目前的情况并不是说我在一个List存储了大量的数据,而是我不得不经常检查它的成员。 问题是我确实需要迭代它,但它们存储或检索的顺序实际上并不重要。 我已经读过,因为每个循环实际上比下一个循环慢,所以我怎么能用尽可能快的方法来解决这个问题呢? 我正在做的.Contains()检查的数量肯定会损害我的列表性能,所以至少与HashSet的性能相比会很方便。 编辑:我目前正在使用列表,在许多位置迭代它们,并且在每个位置执行不同的代码。 大多数情况下,当前列表包含点坐标,然后我用它来引用二维数组,然后根据列表的标准执行某些操作或其他操作。 如果我的问题没有直接的答案,那很好,但我认为可能有其他方法迭代HashSet而不仅仅是foreach循环。 我目前处于黑暗状态,甚至可能有其他方法,它们提供了哪些优势等等。假设还有其他方法,我还假设有一种典型的首选方法,只有在它不能满足需求(我的需求非常基本)。 至于过早优化,我已经知道使用列表,因为我是一个瓶颈。 如何解决这个问题是我陷入困境的地方。 甚至没有完全卡住,但我不想通过重复测试来重新发明轮子只是为了发现我已经尽力做到这一点(这是一个投资超过3个月的大型项目,列表无处不在,但肯定有一些我不想重复,有大量数据,不需要以任何特定顺序存储,等等。

减慢创建具有许multithreading的对象

我正在做一个产生数百个线程的项目。 所有这些线程都处于“hibernate”状态(它们被锁定在Monitor对象上)。 我注意到,如果我增加“hibernate”线程的数量,程序会非常慢。 “有趣”的是,看着任务管理器似乎线程数越多,处理器就越自由。 我已将问题缩小到对象创建。 有人可以向我解释一下吗? 我制作了一个小样本来测试它。 这是一个控制台程序。 它为每个处理器创建一个线程,并通过简单的测试(“新对象()”)测量它的速度。 不,“新的对象()”没有被淘汰(如果你不信任我,试试)。 主线程显示每个线程的速度。 按CTRL-C,该程序产生50个“睡眠”线程。 减速开始只有50个线程。 在任务管理器中,大约250个非常明显,CPU不是100%使用的(我的是82%)。 我已经尝试了三种锁定“hibernate”线程的方法:Thread.CurrentThread.Suspend()(坏,坏,我知道:-)),锁定已经锁定的对象和Thread.Sleep(Timeout.Infinite)。 一样的。 如果我使用新的Object()注释该行,并将其替换为Math.Sqrt(或没有任何内容),则问题不存在。 速度不随线程数而变化。 别人可以查一下吗? 有谁知道瓶颈在哪里? 啊……你应该在发布模式下测试它,不要从Visual Studio中启动它。 我在双处理器上使用XP sp3(没有HT)。 我用.NET 3.5和4.0测试了它(测试不同的框架运行时) namespace TestSpeed { using System; using System.Collections.Generic; using System.Threading; class Program { private const long ticksInSec = 10000000; private const long ticksInMs = ticksInSec / 1000; private const int […]

C#:访问“.NET CLR内存类别”的PerformanceCounters

我正在尝试使用PerformanceCounter类通过C#访问位于“.NET CLR内存类别”中的性能计数器。 但是,无法使用我期望的正确类别/计数器名称来实例化类别 new PerformanceCounter(“.NET CLR Memory”, “# bytes in all heaps”, Process.GetCurrentProcess().ProcessName); 我尝试使用以下代码循环遍历类别和计数器 string[] categories = PerformanceCounterCategory.GetCategories().Select(c => c.CategoryName).OrderBy(s => s).ToArray(); string toInspect = string.Join(“,\r\n”, categories); System.Text.StringBuilder interestingToInspect = new System.Text.StringBuilder(); string[] interestingCategories = categories.Where(s => s.StartsWith(“.NET”) || s.Contains(“Memory”)).ToArray(); foreach (string interestingCategory in interestingCategories) { PerformanceCounterCategory cat = new PerformanceCounterCategory(interestingCategory); foreach (PerformanceCounter counter in […]