在C中将整个文件转换为小写的最佳方法
发布时间:2020-12-16 10:19:48 所属栏目:百科 来源:网络整理
导读:我想知道如果在C中将整个文件转换为较低的Case,那么这是一个非常好的(高性能)解决方案. 我使用fgetc将char转换为小写,并使用fputc将其写入另一个临时文件中.最后,我删除原始文件并将tempfile重命名为旧的原始名称.但我认为必须有一个更好的解决方案. 解决方
我想知道如果在C中将整个文件转换为较低的Case,那么这是一个非常好的(高性能)解决方案.
我使用fgetc将char转换为小写,并使用fputc将其写入另一个临时文件中.最后,我删除原始文件并将tempfile重命名为旧的原始名称.但我认为必须有一个更好的解决方案. 解决方法
如果你正在处理大文件(比如说大数兆字节),而且这个操作对速度至关重要,那么超出你所询问的内容可能是有意义的.特别需要考虑的一点是,逐字符操作的效果不如使用SIMD指令.
即如果您使用SSE2,您可以将toupper_parallel编码为(伪代码): for (cur_parallel_word = begin_of_block; cur_parallel_word < end_of_block; cur_parallel_word += parallel_word_width) { /* * in SSE2,parallel compares are either about 'greater' or 'equal' * so '>=' and '<=' have to be constructed. This would use 'PCMPGTB'. * The 'ALL' macro is supposed to replicate into all parallel bytes. */ mask1 = parallel_compare_greater_than(*cur_parallel_word,ALL('A' - 1)); mask2 = parallel_compare_greater_than(ALL('Z'),*cur_parallel_word); /* * vector op - and all bytes in two vectors,'PAND' */ mask = mask1 & mask2; /* * vector op - add a vector of bytes. Would use 'PADDB'. */ new = parallel_add(cur_parallel_word,ALL('a' - 'A')); /* * vector op - zero bytes in the original vector that will be replaced */ *cur_parallel_word &= !mask; // that'd become 'PANDN' /* * vector op - extract characters from new that replace old,then or in. */ *cur_parallel_word |= (new & mask); // PAND / POR } 即您可以使用并行比较来检查哪些字节是大写的,然后在您或它们一起形成结果之前屏蔽原始值和“大写”版本(一个带掩码,另一个带反面). 如果你使用mmap的文件访问,这甚至可以就地执行,保存在反弹缓冲区,并节省许多功能和/或系统调用. 当你的起点是逐个字符的’fgetc’/’fputc’循环时,有很多要优化的东西;即使是shell实用程序也很可能比这更好. 但我同意,如果您的需求是非常特殊的(即像ASCII输入那样明确的东西要转换为大写),那么使用矢量指令集(如SSE内在函数/汇编或ARM NEON,如上所述)手工循环或者PPC Altivec),可能比现有的通用公用事业产生显着的加速. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |