gpt4 book ai didi

c - 如何从标准输入获取整数?快速地。可以用准确性换取性能

转载 作者:行者123 更新时间:2023-11-30 18:12:53 25 4
gpt4 key购买 nike

我正在尝试想出一个快速而简单的

"Get a string from stdin and convert to an integer. If you can't, just pretend we got zero".

这是一个Linux嵌入式系统,CPU和内存都很宝贵。性能很重要,准确性并不那么重要。这应该能够每秒进行多次摄取。我最终会将它变成一个守护进程,并将最新的 1024 个值存储在一个数组中。

这是我使用 atoi 的看法:

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[] ) {
char *c = argv[1];
unsigned int i = 1; /* on atoi() failure, i = 0 */

if (i = atoi(c)) {
puts ("atoi() success");
}
else {
puts ("atoi() FAILED");
}

printf("argv[1] = %s\n", argv[1]);
printf(" i = %d\n", i);
}

一些测试运行/模糊测试:

# ./test_atoi 3
atoi() success
argv[1] = 3
i = 3

# ./test_atoi 99999999999999999999
atoi() success
argv[1] = 99999999999999999999
i = 2147483647

# ./test_atoi 3.14159
atoi() success
argv[1] = 3.14159
i = 3

# ./test_atoi $(echo -ne "\u2605")
atoi() FAILED
argv[1] = ★
i = 0

这失败了:

# ./test_atoi $(echo -e "\0")
Segmentation fault

然后我将添加对 NUL 的检查:

if (argv[1] == '\0') {
i = 0;
}

这够了吗?我刚刚(糟糕地)重新实现了 strtol 吗?我应该继续使用 strtol 吗?如果是的话,我应该检查什么,strtol 还没有检查吗?

我真正关心的是不会因为错误的输入而死亡。我可以愉快地忍受转换中偶尔出现的垃圾。

编辑:int i = 1只是因为我想看看atoi()是否使它为0。

贫民窟随时间的剖析

编辑:我已经删除了 print 语句,并将从 stdin 的读取包装到 for 循环中的 atoi/strtol 中。

# time seq 0 999888 | ./test_atoi
real 0m5.245s
user 0m5.870s
sys 0m0.030s

# time seq 0 999888 | ./test_atoi
real 0m5.230s
user 0m5.960s
sys 0m0.050s

# time seq 0 999888 | ./test_atoi
real 0m5.395s
user 0m5.920s
sys 0m0.080s

# time seq 0 999888 | ./test_strtol
real 0m5.332s
user 0m5.860s
sys 0m0.030s

# time seq 0 999888 | ./test_strtol
real 0m5.023s
user 0m5.790s
sys 0m0.060s

# time seq 0 999888 | ./test_strtol
real 0m5.286s
user 0m5.970s
sys 0m0.010s

好吧,这太疯狂了。我应该利用我和你的时间做一些更有成效的事情!

最佳答案

This is a Linux embedded system, CPU and memory are at a premium.

是的。呃,不。如果您运行的是普通 Linux,您的内核将在数千个地方使用 atoi 和相反的情况。您的单个数字解析器几乎不会产生任何影响,除非您打算每秒调用它数千次...

Should i just go ahead and use strtol?

出于上述原因:是的。

If yes, anything i should be checking for, that strtol isn't already?

您应该检查strtol的返回值。我真的不同意你的“不需要精确”的做法。像这样的事情要么做得正确,要么做得灾难性的错误。

编辑你说:

don't need precision = i only care about values 0 - 100

这意味着a)您只需要atoi,而不是atol/strtol;在那里,CPU 周期被节省了。接下来,您是否确实需要将看起来像 13.288 的字符串转换为整数,或者您是否可以假设所有字符串的长度都是 1 到 3 个字符?在这种情况下,对于原始性能,也许

inline unsigned char char2digit(const char *c) {
unsigned char v = *c - '0';
return (v<1 || v>9)? 0 : v;
}
inline signed char characters2number(const char *string)
{
size_t len = strnlen(string,4);
if(len < 1 || len > 3)
return -1;
signed char val = 0;
signed char power_of_ten = 1;
for(unsigned char idx = 1; idx <= len; ++idx)
{
signed char val += power_of_ten * char2digit(string + len - idx)
power_of_ten *= 10;
}
return val;
}

我的意思是,如果你在 toastr 上。否则,atoi 会为您提供支持。您可能仍想检查 strnlen

关于c - 如何从标准输入获取整数?快速地。可以用准确性换取性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29470693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com