我正在玩C#,想加快一个程序.我做了改变,并且能够这样做.但是,我需要帮助理解为什么变化使它变得更快.
我试图将代码简化为更容易理解的问题.Score1和Report1是较慢的方式.Score2和Report2是更快的方式.第一种方法首先并行地在结构中存储字符串和int.接下来,在串行循环中,它循环遍历这些结构的数组并将其数据写入缓冲区.第二种方法首先将数据并行写入字符串缓冲区.接下来,在串行循环中,它将字符串数据写入缓冲区.以下是一些示例运行时间:
运行1总平均时间= 0.492087秒运行2总平均时间= 0.273619秒
当我使用早期的非并行版本时,时间几乎相同.为什么与并行版本的区别?
即使我减少Report1中的循环以将单行输出写入缓冲区,它仍然较慢(总时间约为.42秒).
这是简化的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.IO;
namespace OptimizationQuestion
{
class Program
{
struct ValidWord
{
public string word;
public int score;
}
ValidWord[] valid;
StringBuilder output;
int total;
public void Score1(string[] words)
{
valid = new ValidWord[words.Length];
for (int i = 0; i < words.Length; i++)
{
StringBuilder builder = new StringBuilder();
foreach (char c in words[i])
{
if (c != 'U')
builder.Append(c);
} …Run Code Online (Sandbox Code Playgroud) 是否有任何工具可以从正在运行的应用程序中获取堆转储并根据源代码的创建位置确定/分组对象?
没有更改源代码,理想情况下是免费的.
我的Visual Studio(2010 SP1)有严重的内存泄漏,它似乎是由一个或多个已安装的扩展引起的.
我试图通过打开和关闭扩展和附加组件来缩小范围,但是需要花费一些时间来构建重大泄漏,结果并不完全是结论性的.在devenv.exe进程使用2GB内存并开始丢弃之前,它很少需要几个小时,这对于使用起来有点麻烦.
有没有办法让VS在为扩展分配的内存上发出信息?
托管扩展是否在自己的AppDomain中运行?也许这会让我打开一些可以帮助查明问题的性能计数器.
还有什么我可以解决这个问题,除了逐个禁用东西,直到问题消失?
我正在做其他实验,直到这种奇怪的行为引起了我的注意.
代码在x64版本中编译.
如果键入1,则第3次运行List方法的成本比前2个多40%.输出是
List costs 9312
List costs 9289
Array costs 12730
List costs 11950
Run Code Online (Sandbox Code Playgroud)
如果键入2,则第三次运行Array方法的时间比前两次多30%.输出是
Array costs 8082
Array costs 8086
List costs 11937
Array costs 12698
Run Code Online (Sandbox Code Playgroud)
你可以看到模式,完整的代码附在下面(只是编译和运行):{提供的代码是最小的运行测试.用于获得可靠结果的实际代码更复杂,我将方法包装好并在适当的预热后测试了100多次}
class ListArrayLoop
{
readonly int[] myArray;
readonly List<int> myList;
readonly int totalSessions;
public ListArrayLoop(int loopRange, int totalSessions)
{
myArray = new int[loopRange];
for (int i = 0; i < myArray.Length; i++)
{
myArray[i] = i;
}
myList = myArray.ToList();
this.totalSessions = totalSessions;
}
public void ArraySum()
{ …Run Code Online (Sandbox Code Playgroud) 我有一个用C#/ .NET 3.5编写的客户端/服务器应用程序,我想对其进行一些性能测试.我一直在寻找一个通用的框架来帮助我,但没有太多运气.我想要一些可以管理一组客户端并根据某些设置为它们执行随机操作的东西.然后我还想记录一些与此相关的数据,以帮助我为我的系统工作超出粗略的阈值,例如,我可以支持n个用户每秒执行x次操作.
我会编写特定于我的应用程序的代码来执行以下任务:
我希望框架能够采用一组参数来描述测试场景,例如:
然后它将运行场景,管理和跟踪所有用户和操作并整理所有数据.(这是我试图避免自己编码的无聊位...)理想情况下,它会内置一些常规测量,例如发送消息和接收响应之间的时间,但如果没有,我可以自己编码.
我不想对我的代码进行任何分析; 我可以随后在运行这些测试时附加一个分析器.相反,我想对我的系统作出一些粗略的结论,即在断开之前我可以抛出多少用户.(如果有一个比'性能测试'更好的术语,请告诉我......压力测试可能吗?)
我意识到我在这里没有提供很多关于系统的细节.这让我感觉相当普遍 - 我确信有很多客户端/服务器系统需要人们进行类似的测试.我发现很多基于Web的框架都可以做类似的事情,但它们看起来很网络,并且不适合非基于HTTP的系统.
有人知道任何可能有用的东西吗?我的搜索还没有找到任何东西.我应该指出,我已经坚持使用Visual Studio 2008 Professional以实现可预测的未来,所以如果2010年可以做到这一点,那对我来说是不合适的.我想它不一定是.NET框架,只要我仍然可以很容易地插入我的.NET代码.
编辑要清楚我的应用程序不是一个网站,它是一个Windows窗体客户端应用程序,通过自定义协议连接到.NET服务.我可以编写代码来执行相关的客户端操作,我只需要一个框架来放入它.
我有一个在.NET 3.5上运行的独立WPF应用程序.每隔一段时间,显示屏就会冻结几秒钟.这在经常更新某些内容的屏幕上最为明显.这是一个显示问题的视频.
当显示器冻结时,界面保持响应(视频).
我遇到过一些其他类似问题的帖子,这些帖子将其归因于SW/HW渲染问题.为了安全起见,我完全禁用了硬件渲染,但仍然存在问题.
我在冻结期间运行了一个文件监视器,看看是否有一些特殊的文件访问或活动,但没有什么是不寻常的.
最后说明:目标平台是一款小型触摸屏平板电脑,没有太多内存或马力(512 MB).我只在目标上看到这个问题,而不是在我的开发PC上,它在资源方面有更多.
UPDATE
我以为我通过删除一些动画代码修复了这个问题,但它没有用.我仍然遇到这个问题而且我已经到了最后.
这是我尝试过的更多内容:
我真的很难过,并且增加了赏金.正如我所提到的,问题只发生在目标PC(链接)上.
如何在 C# 中测试性能?
我现在所知道的就是使用:
Stopwatch sw = new Stopwatch();
sw.Start();
{
//code to test
}
sw.Stop();
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以做到这一点还是上述方法错误?
在我的一些异步tcp服务器代码中,偶尔会发生错误,导致进程占用整个系统的内存.在查看日志,事件查看器和一些MS文档时,如果"调用应用程序多次向同一客户端调用异步IO,那么如果远程客户端停止其结束,则可能会看到堆碎片和私有字节增加"/O"导致内存使用量激增以及System.Threading.OverlappedData结构和字节数组的固定.
知识库文章提出的解决方案是"设置未完成缓冲区(发送或接收)与异步IO的上限."
怎么做到这一点?这是指发送到BeginRead的byte []吗?那么解决方案只是用信号量包装访问byte []?
编辑:信号量控制访问字节缓冲区或只是具有静态大小的字节缓冲池是两种常见的解决方案.我仍然存在的一个问题是,当这个异步客户端问题发生时(实际上它可能是一些奇怪的网络事件)有信号量或字节缓冲池将阻止我耗尽内存,但它无法解决问题.我的缓冲池可能会被问题客户端吞噬,实际上锁定了正确的函数合法客户端.
编辑2:遇到了这个伟大的答案.基本上它显示了如何手动取消固定对象.虽然异步TCP代码可以固定到幕后运行时规则,但有可能通过在使用前明确地固定每个缓冲区来覆盖它,然后在块的末尾或最后一个中取消固定.我现在想弄明白......
编辑:赏金已过期,但如果社区想将其奖励给某人,那么我选择 Raful Chizkiyahu。
我的一个 C# Winforms 程序中存在内存泄漏,我想绘制其内存使用情况随时间变化的图表,以便更好地了解可能导致泄漏的原因。问题是,没有一个常用的内存诊断命令与任务管理器声称的该进程消耗的内存相匹配。我认为这可能是由于使用不安全/非托管代码的应用程序未包含在总数中。
因此,为了尝试深入研究,我创建了一个新的 Winforms 应用程序,非常简单,只有一个计时器来实时报告内存使用情况。我用5个标签,各家有各家的功能(主要是发现从这里开始): ,Environment.WorkingSet,,和。GC.GetTotalMemory(false)GC.GetTotalMemory(true)Process.GetCurrentProcess().PrivateMemorySize64Process.GetCurrentProcess().WorkingSet64
令人惊讶的是(或者可能不是这样,叹气),我仍然无法让这五个数字中的任何一个与 Windows 10 任务管理器相匹配。这是一个屏幕截图:

所以我基本上要寻找的是 5.1MB 的数字。我如何偷偷地从 .NET 框架中提取那个隐藏的数字?
这是我在 Timer 滴答函数中的代码:
private void timer1_Tick(object sender, EventArgs e)
{
//Refresh();
label1.Text = "Environment.WorkingSet: " + Environment.WorkingSet ;
label2.Text = "GC.GetTotalMemory(false): " + GC.GetTotalMemory(false) ;
label3.Text = "GC.GetTotalMemory(true): " + GC.GetTotalMemory(true) ;
Process proc = Process.GetCurrentProcess();
label4.Text = "proc.PrivateMemorySize64: " + proc.PrivateMemorySize64 ;
label5.Text = "proc.WorkingSet64: " + proc.WorkingSet64 ;
proc.Dispose();
} …Run Code Online (Sandbox Code Playgroud) 我有一个基于 ASP.NET 用 C# 编写的 webapp。它加载(使用LoadLibraryEx)一个用 C++Builder 编写的非托管 DLL。
由于我有性能问题,我做了一些测试和比较,在 DLL 中始终运行相同的方法多次,获得平均时间。
我发现DLL:
如您所见,案例 1 和案例 2 的性能非常相似。
为什么情况 3 这么慢?也许 IIS 会减慢 DLL 的速度?
为此,我使用 JetBrains dotTrace 进行了分析:

是否有任何建议的 IIS 调整?
是否有任何建议的快速替代 IIS 来托管 ASP.NET webapps?
我应该考虑将 webapp 移植到 C++Builder 吗?
编辑:
我尝试将我的 webapp 迁移到 ASP.NET Core(而不是 .NET Framework)并在 Kestrel 上运行它。需要 6.042 秒。因此,与控制台应用程序相比,开销并不大。看来IIS是罪魁祸首......为什么?
c# ×8
.net ×4
performance ×4
memory-leaks ×2
testing ×2
asp.net ×1
asynchronous ×1
c#-4.0 ×1
freeze ×1
iis ×1
memory ×1
profiling ×1
rendering ×1
taskmanager ×1
tcp ×1
unmanaged ×1
winforms ×1
wpf ×1