关于fseek, fwrite, fread的耗时问题

KCDKFT 2015-04-28 03:41:07
现在有一个文件存储着一些样本,目的是随机打乱这些样本
我的做法是这样的
1. 将样本拷贝
2. 生成随机样本的位置索引
3. fread原数据的一个样本
4. 根据位置索引调用fseek,找到在随机化之后的位置
5. fwrite这个样本的数据到拷贝的文件中

这个过程极其耗时,但是我将fread, fseek, fwrite三个函数随便选一个注释掉,效率都会有大幅度提升,不知道这是为什么?
...全文
1376 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-05-01
  • 打赏
  • 举报
回复
引用 12 楼 kuaitoukid 的回复:
[quote=引用 11 楼 zhao4zhong1 的回复:] 提醒楼主:超过2GB的文件好象不能用fseek得改用_fseeki64(Windows)或fseeko64(Linux)了吧。
我这并没有报错,7个G的文件……[/quote] 那可能是因为你用64位编译环境且在64系统下运行。
KCDKFT 2015-04-30
  • 打赏
  • 举报
回复
引用 11 楼 zhao4zhong1 的回复:
提醒楼主:超过2GB的文件好象不能用fseek得改用_fseeki64(Windows)或fseeko64(Linux)了吧。
我这并没有报错,7个G的文件……
赵4老师 2015-04-29
  • 打赏
  • 举报
回复
提醒楼主:超过2GB的文件好象不能用fseek得改用_fseeki64(Windows)或fseeko64(Linux)了吧。
赵4老师 2015-04-29
  • 打赏
  • 举报
回复
现在Win64位系统高配的话,内存是多少G来着?
KCDKFT 2015-04-29
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
高兴了楼主试试将文件放在RAMDISK上,估计打火机没从兜里掏出来就over了。
多谢多谢,我看看,感觉好高端= =
KCDKFT 2015-04-29
  • 打赏
  • 举报
回复
引用 6 楼 dooX8086 的回复:
有 io 操作当然耗时.加上大量的 fseek (如果是非固态硬盘会跳硬盘磁头....巨耗时) 内存够大,一般都采用 空间换时间 的方法. 1) 采用内存映射文件方法进行操作, 2), 采用 一次 fread() 所以数据,---> 处理 ----> 一次 fwrite()所有数据 // ------------------------------------------- 记得N久久前实现一数据整理功能. 用边读边处理边写方法 耗时: 吸一根烟时间 一次读入处理一次写方法 耗时: 点一根烟时间
7个G的数据啊……读入内存不现实啊,还是说把7个G拆成小部分分别处理?
赵4老师 2015-04-28
  • 打赏
  • 举报
回复
高兴了楼主试试将文件放在RAMDISK上,估计打火机没从兜里掏出来就over了。
dooX8086 2015-04-28
  • 打赏
  • 举报
回复
有 io 操作当然耗时.加上大量的 fseek (如果是非固态硬盘会跳硬盘磁头....巨耗时) 内存够大,一般都采用 空间换时间 的方法. 1) 采用内存映射文件方法进行操作, 2), 采用 一次 fread() 所以数据,---> 处理 ----> 一次 fwrite()所有数据 // ------------------------------------------- 记得N久久前实现一数据整理功能. 用边读边处理边写方法 耗时: 吸一根烟时间 一次读入处理一次写方法 耗时: 点一根烟时间
赵4老师 2015-04-28
  • 打赏
  • 举报
回复
再供参考:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned long ulrand(void) {
    return (
     (((unsigned long)rand()<<24)&0xFF000000ul)
    |(((unsigned long)rand()<<12)&0x00FFF000ul)
    |(((unsigned long)rand()    )&0x00000FFFul));
}
unsigned __int64 ullrand(void) {
    return (
     (((unsigned __int64)ulrand())<<32)
    | ((unsigned __int64)ulrand()));
}
int i;
unsigned long ul;
unsigned __int64 ull;
void main() {
    srand(time(NULL));
    for (i=0;i<10;i++) {
        ul=ulrand();
        printf("%010lu 0x%08x\n",ul,ul);
    }
    for (i=0;i<10;i++) {
        ull=ullrand();
        printf("%020I64u 0x%016I64x\n",ull,ull);
    }
}
//3971076432 0xecb1d150
//2433428051 0x910b2a53
//1415415336 0x545d8628
//1312330759 0x4e389407
//1845758378 0x6e0409aa
//0008069933 0x007b232d
//4202720757 0xfa806df5
//2669855255 0x9f22c217
//0312068736 0x1299ca80
//2084555989 0x7c3fccd5
//03502077880857307931 0x3099e1472040ab1b
//16884702393146816355 0xea52835e19b43763
//01877364819396611730 0x1a0dbd5b45f34e92
//07839440151924835771 0x6ccb4948756a05bb
//09471412086917299176 0x8371371c820bfbe8
//04411255971577469925 0x3d37edef2f321be5
//13735846279546091130 0xbe9f876a65b7367a
//04512980766520059820 0x3ea15418aa9927ac
//15821377118299441610 0xdb90d2a9f1bb49ca
//15512417228822200185 0xd7472d480398bf79

赵4老师 2015-04-28
  • 打赏
  • 举报
回复
仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int d[6];
int i,n,a,b,t;
int c,j;
void main() {
    srand(time(NULL));
    printf("shuffle 0..n-1 demo\n");
    for (n=1;n<=5;n++) {/* 测试1~5个元素 */
        printf("_____n=%d_____\n",n);
        j=1;
        for (c=1;c<=n;c++) j=j*c;/* j为n! */
        j*=n*2;
        for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
            for (i=0;i<n;i++) d[i]=i;/* 填写0~n-1 */
            for (i=n;i>0;i--) {/* 打乱0~n-1 */
                a=i-1;b=rand()%i;
                if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
            }
            printf("%04d:",c);
            for (i=0;i<n;i++) printf("%d",d[i]);
            printf("\n");
        }
    }
    printf("shuffle 1..n demo\n");
    for (n=1;n<=5;n++) {/* 测试1~5个元素 */
        printf("_____n=%d_____\n",n);
        j=1;
        for (c=1;c<=n;c++) j=j*c;/* j为n! */
        j*=n*2;
        for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
            for (i=1;i<=n;i++) d[i]=i;/* 填写1~n */
            for (i=n;i>1;i--) {/* 打乱1~n */
                a=i;b=rand()%i+1;
                if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
            }
            printf("%04d:",c);
            for (i=1;i<=n;i++) printf("%d",d[i]);
            printf("\n");
        }
    }
}
KCDKFT 2015-04-28
  • 打赏
  • 举报
回复
引用 1 楼 a30037338 的回复:
数据量很大吗,没完全明白你的意思, 打乱(读取出来在写回去?),生成索引(索引存在哪里),按索引查找(怎么查找),你仔细想想你的逻辑处理上有没有可优化的。
我是用MATLAB的randperm来生成的索引 = =
KCDKFT 2015-04-28
  • 打赏
  • 举报
回复
引用 1 楼 a30037338 的回复:
数据量很大吗,没完全明白你的意思, 打乱(读取出来在写回去?),生成索引(索引存在哪里),按索引查找(怎么查找),你仔细想想你的逻辑处理上有没有可优化的。
数据量很大,400万的样本量,是写到拷贝的样本里面,肯定不能直接写到原样本,这样就覆盖了,索引是提前生成好的,每次都要fread这个索引文件来获取fseek的位置
此后三年 2015-04-28
  • 打赏
  • 举报
回复
数据量很大吗,没完全明白你的意思, 打乱(读取出来在写回去?),生成索引(索引存在哪里),按索引查找(怎么查找),你仔细想想你的逻辑处理上有没有可优化的。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧