读取大文件时如何避免高 cpu 使用率
how to avoid high cpu usage when reading large files
我的项目使用 BackgroundThread 将 hugh 字符串列表加载到列表视图中,它的性能非常快,但占用了将近 100% cpu 是否有任何解决方法可以避免高 cpu 使用率而不降低其使用率表现?我使用网络框架 3.5
代码:
void readfile() {
deg_readfile read = new deg_readfile(readfileasync);
read.BeginInvoke(new AsyncCallback(callback),null);
}
void readfileasync(){
string[] strs = File.ReadAllLines("hughlist.txt");
List<ListViewItem> _itemlst = new List<ListViewItem>();
ListViewItem _item;
int x = 0;
//problem start here
foreach (string str in strs) {
_item = new ListViewItem(str);
for (int i = 0; i < 6; i++) {
_item.SubItems.Add("");
}
_itemlst.Add(_item);
x++;
_item = null;
}
}
void callback(IAsyncResult ae) {
Console.WriteLine("finished");
}
delegate void deg_readfile();
static void Main(string[] args)
{
Program prog = new Program();
Thread t=new Thread(new ThreadStart(prog.readfile))
{
IsBackground = true,
Priority = ThreadPriority.Lowest
};
t.SetApartmentState(ApartmentState.MTA);
t.Start();
Console.Read();
}
提前致谢。
更新:
系统配置:
处理器:Intel(R) Core(TM) i3-2328M CPU @ 2.20GHZ 2.11 GHZ
安装内存:1.00 GB
系统类型:32位操作系统
文件大小为 35,939 KB,包含 100 万行
这不是异步的:您只是使用不同的线程来调用 invoke,传递的委托将 运行 在主 (GUI) 线程中同步(因为控件与创建的线程相关联)他们:主线程)。
所以工作线程做了两件事:
- 创建线程
- 线程池线程上的调用操作
完成了。
线程池线程完成所有工作,包括同步读取文件。2
但是,单个文件 IO 不太可能1占用大量时间;然后在第一个 运行 之后,它将被缓存在内存中,从而减少 IO 时间来调度内核调用。
但是异步执行不会减少所需的 CPU 资源量(这是可能的 – 设置数据结构来跟踪事情 – 这将需要更多):您的 CPU 将参与处理文件的内容。
您或许可以对其进行优化,但您需要从探查器数据开始,以了解 CPU 时间花在了哪些地方。
1 如果文件存在于具有高延迟或低带宽连接的网络共享上,它可能会有所不同。
2 严格来说,在线程池线程上执行阻塞操作是一种糟糕的形式(它们不可用于其他活动)但不太可能成为文件 IO 的问题。 (见上一个脚注。)
我的项目使用 BackgroundThread 将 hugh 字符串列表加载到列表视图中,它的性能非常快,但占用了将近 100% cpu 是否有任何解决方法可以避免高 cpu 使用率而不降低其使用率表现?我使用网络框架 3.5
代码:
void readfile() {
deg_readfile read = new deg_readfile(readfileasync);
read.BeginInvoke(new AsyncCallback(callback),null);
}
void readfileasync(){
string[] strs = File.ReadAllLines("hughlist.txt");
List<ListViewItem> _itemlst = new List<ListViewItem>();
ListViewItem _item;
int x = 0;
//problem start here
foreach (string str in strs) {
_item = new ListViewItem(str);
for (int i = 0; i < 6; i++) {
_item.SubItems.Add("");
}
_itemlst.Add(_item);
x++;
_item = null;
}
}
void callback(IAsyncResult ae) {
Console.WriteLine("finished");
}
delegate void deg_readfile();
static void Main(string[] args)
{
Program prog = new Program();
Thread t=new Thread(new ThreadStart(prog.readfile))
{
IsBackground = true,
Priority = ThreadPriority.Lowest
};
t.SetApartmentState(ApartmentState.MTA);
t.Start();
Console.Read();
}
提前致谢。
更新:
系统配置:
处理器:Intel(R) Core(TM) i3-2328M CPU @ 2.20GHZ 2.11 GHZ 安装内存:1.00 GB 系统类型:32位操作系统
文件大小为 35,939 KB,包含 100 万行
这不是异步的:您只是使用不同的线程来调用 invoke,传递的委托将 运行 在主 (GUI) 线程中同步(因为控件与创建的线程相关联)他们:主线程)。
所以工作线程做了两件事:
- 创建线程
- 线程池线程上的调用操作
完成了。
线程池线程完成所有工作,包括同步读取文件。2
但是,单个文件 IO 不太可能1占用大量时间;然后在第一个 运行 之后,它将被缓存在内存中,从而减少 IO 时间来调度内核调用。
但是异步执行不会减少所需的 CPU 资源量(这是可能的 – 设置数据结构来跟踪事情 – 这将需要更多):您的 CPU 将参与处理文件的内容。
您或许可以对其进行优化,但您需要从探查器数据开始,以了解 CPU 时间花在了哪些地方。
1 如果文件存在于具有高延迟或低带宽连接的网络共享上,它可能会有所不同。
2 严格来说,在线程池线程上执行阻塞操作是一种糟糕的形式(它们不可用于其他活动)但不太可能成为文件 IO 的问题。 (见上一个脚注。)