V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  zungmou  ›  全部回复第 9 页 / 共 14 页
回复总数  263
1  2  3  4  5  6  7  8  9  10 ... 14  
2015-04-11 12:09:17 +08:00
回复了 kn007 创建的主题 问与答 大伙对理发器有了解不?推荐一个?
@kn007 脑门后面的头发,自己怎么修理?
2015-04-07 14:18:53 +08:00
回复了 xgdyhaiyang 创建的主题 职场话题 有辞职全职做交易的 V2EXer 吗?
小做做可以,发家致富靠赌。
2015-04-04 21:53:02 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@ncisoft 您很细心~ 改成long类型,200MB平均耗时0.76秒,总耗时21秒。
2015-04-04 21:29:17 +08:00
回复了 oojiayu 创建的主题 程序员 看雪学院(看雪论坛)——有没有 V2 的朋友常去转转的
X档案也是我入门编程的第一本杂志,当年每一期都附带一张光盘,那会还是 FLASH 的天下,每期的多媒体光盘都是用 FLASH 做的很精美,X档案应该是一代人的回忆。
2015-04-04 21:03:30 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@wuxqing
@billlee
@ncisoft
@batman2010
@Andiry
@yangff

最后一个问题,为什么 x64 比 x86 进行 for 循环所需的时间更长?
2015-04-04 21:02:23 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@wuxqing
@billlee
@ncisoft
@batman2010
@Andiry
@yangff

首先感谢各位的回复。

我的操作系统是 Win7 x64,CPU I5-4430主频3G,内存16GB,普通机械硬盘,开发环境是VS2013+C#;
经过一夜优化调试,现总结给大家,一个5G 文件,扫描统计后的结果如下:

x64编译:
每200MB扫描耗时0.85秒(不包括IO时间)
总耗时23.37秒(包括IO时间)

x86编译:
每200MB扫描耗时0.58秒(不包括IO时间)
总耗时16.66秒(包括IO时间)

优化主要将C#的数组改为指针去统计,绕过托管内存的消耗。
当中试过并行计算,使用的是.NET的并行类,但扫描时间比 for 循环稍长。

备注:每次缓存的数据大小和扫描时间成正比增长,所以不考虑是否全部载入内存。

源代码如下:

unsafe static class Analyzing
{
public static int[] Count(Stream stream)
{
byte[] buffer = new byte[204800000];
int read = 1;

// 用于保存统计数据的内存。
int* count = (int*)Marshal.AllocHGlobal(sizeof(int) * 256);

// 用0填充内存;
for (int i = 0; i < 256; i++)
{
count[i] = 0;
}

// 记录工作开始的时间。
DateTime begin = DateTime.Now;

// 循环读取数据到内存;
while (read > 0)
{
read = stream.Read(buffer, 0, buffer.Length);
if (read == 0) break;
// 记录扫描开始的时间。
DateTime start = DateTime.Now;
// 扫描内存的数据,并进行统计;
// count为int类型,256大小的内存区域;
// count的索引位置(0-255),代表字节0-255;
// count的索引内容,代表字节出现的频率。
for (int i = 0; i < read; i++)
{
count[buffer[i]]++;
}
// 输出扫描耗费的时间。
Console.WriteLine((DateTime.Now - start).TotalSeconds);
}

Marshal.FreeHGlobal((IntPtr)count);

// 输出工作耗费的时间。
Console.WriteLine((DateTime.Now - begin).TotalSeconds);
Console.ReadKey();

// 将非托管内存转换为托管数组,并返回该结果。
int[] result = new int[256];
Marshal.Copy((IntPtr)count, result, 0, result.Length);

return result;
}
}
2015-04-04 09:33:34 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@Andiry mmap 虽然映射过去了,可IO时间真的能缩减吗?
2015-04-04 09:12:26 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@ncisoft 十分感谢您的回复。

C#的MemoryMappedFile是封装mmap的类,当使用mmap方法和直接读取文件做对比,感觉性能差不了多少,基于C#测试。

public static int[] Count(Stream stream)
{
byte[] buffer = new byte[204800000];
int read = 1;
int[] count = new int[256];

DateTime begin = DateTime.Now;
while (read > 0)
{
read = stream.Read(buffer, 0, buffer.Length);
if (read == 0) break;

DateTime start = DateTime.Now;
for (int i = 0; i < read; i++)
{
count[buffer[i]]++;
}
Console.WriteLine((DateTime.Now - start).TotalSeconds);
}
Console.WriteLine((DateTime.Now - begin).TotalSeconds);
Console.ReadKey();
return count;
}

我把统计方法封装成上面这段函数,用于统计一个流内出现的字节频率,可以输入FileStream或MemoryMappedFileStream。每读取200MB的数据到缓存,扫描的平均时间(不包括IO时间)为1.40秒左右,读取一个4.78G的文件总耗费37秒左右。

不知以上方法是否还能再优化?
2015-04-03 22:51:35 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@batman2010 直接用 int[] 不是比任何Cache都要快吗?索引位置代表字节,数组值代表出现的次数。
2015-04-03 22:34:13 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@wuxqing 1s 这么快?用 for 循环能做到 1s 扫完 5G 内存?
2015-04-03 22:29:32 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@ncisoft 给出 C# 代码。

class VScan
{
MemoryMappedFile _mappedFile;
MemoryMappedViewAccessor _viewAccessor;
long _position;
int[] _count;

public VZipStream(string filename)
{
_mappedFile = MemoryMappedFile.CreateFromFile(filename, FileMode.Open, "VScan");
_viewAccessor = _mappedFile.CreateViewAccessor();
_count = new int[256];
}

public void Compress(Stream output)
{
byte[] buffer = new byte[20480000];
int read = 1;

while (read > 0)
{
read = _viewAccessor.ReadArray(_position, buffer, 0, buffer.Length);
if (read == 0) break;
_position += read;

for (int i = 0; i < read; i++)
{
_count[buffer[i]]++;
}

Console.WriteLine(_position);
}
}

~VScan()
{
_viewAccessor.Dispose();
_mappedFile.Dispose();
}
}
2015-04-03 22:19:47 +08:00
回复了 zungmou 创建的主题 C 高效扫描一个大文件内字节出现的频率?
@wuxqing 这样的速度非常慢,慢在扫描的过程。
2015-03-28 13:55:19 +08:00
回复了 Tlvncks 创建的主题 分享发现 谷歌推出了 Chrome 流量节省扩展.效果还不错
如果不带套的话,这个服务用的 Google 的 IP 默认应该使用不了吧。
2015-02-13 23:20:26 +08:00
回复了 kankana 创建的主题 程序员 程序犯了好些小错误,出事了,现在坐立不安
对于运行的系统,从不去删除数据,只有空间不足时通过数据维护的功能对距离时间最久的数据进行删除。
已入 6+
2015-02-10 23:43:27 +08:00
回复了 lvwzhen 创建的主题 问与答 js 如何模拟 ios 中的列表滑动删除效果?
在桌面显示器上滑动有什么意义?
2015-01-18 21:45:46 +08:00
回复了 zungmou 创建的主题 奇思妙想 是否存在多重宇宙,我是不是想太多了?
@cooper 哥们 你真厉害
2015-01-17 16:54:47 +08:00
回复了 zungmou 创建的主题 奇思妙想 是否存在多重宇宙,我是不是想太多了?
@Mutoo
@bugeye

俩位的回答让我想到:“为什么我还活着”这个命题,既然人在宇宙中如此渺小,小到生命存在与否对于宇宙来说都不重要,那么可以把活着和死亡看作两种状态,这两种状态的转变是随机性的,无论你相信与否它都会发生。
2015-01-14 14:15:06 +08:00
回复了 tboy 创建的主题 程序员 视频 图片 压缩技术
算法能开源的话,才会对人类社会有更大帮助。
1  2  3  4  5  6  7  8  9  10 ... 14  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1162 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 25ms · UTC 18:07 · PVG 02:07 · LAX 10:07 · JFK 13:07
Developed with CodeLauncher
♥ Do have faith in what you're doing.