如果我将数字转换为字符串,在数字中找到 0 会更快吗?
Would finding 0 in a number be faster if I convert the number to a string?
我需要确定一个数字中是否包含 0。到目前为止,我已经尝试用 10 对数字取模,然后将商除以 10,然后重复此过程直到数字为 0。正在将此数字转换为字符串并使用 .contains 搜索此字符串() 方法效率更高?
我的代码:
boolean zero(int n) {
if(n == 0)
return true;
while(n > 0) {
if(n % 10 == 0)
return true;
n = n/10;
}
return false;
}
如有任何帮助,我们将不胜感激。
嗯,实际上,想一想字符串,每个数字,是如何 'created':除以 10 的模数。所以 int-to-String 转换实际上会完成与您正在做的相同的任务.
这是 Integer.getChars()
的源代码,这是通过 Integer.toString()
调用的,以及一些其他缓冲区管理:
static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
i = -i;
}
// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}
如您所见,它使用比 65536 更大的数字,并改进了除法转换循环。对于较低的数字(或者一旦原始数字被削减),有一些大量的优化(位移和字节掩码)并继续进行。
除法通常成本更高,比位移慢 20 到 60 倍。所以最后一部分真的很快。但这只是5位数,那会有多大影响呢?
还要考虑内存管理。 JVM 可能 运行 如果您的系统在所有内核上保持 运行ning 100%,并且当(如果)可能必须进行垃圾收集时,GC 引发的 'forced'暂停可能会消除所有速度优势。 (测试这个应该是分分钟的长期测试)。
您也可以考虑将 problem/tasks 拆分到多个线程中。最简单的方法是使用 java 1.8-new 流。或者你有自己的 parallelizer/splitter 和自己的任务 arrays/queues。可能几乎是任务速度的 n 倍,n 是您可以使用的 CPU 个核心数。
正如其他人所说,实际上最好自己测试速度。
最好写一个 运行 大约 10 秒的测试。这足够长,可以为您提供稳定的估算和启动 JIT 优化,也足够短,不会让您感到厌烦。
另一方面,通常最好以明显的、不神秘的、易于维护的方式解决问题。因此,如果我必须实施它,我会进行测试,如果差异小于 5 倍,我会坚持只使用数字。没有附加条件:-D
我需要确定一个数字中是否包含 0。到目前为止,我已经尝试用 10 对数字取模,然后将商除以 10,然后重复此过程直到数字为 0。正在将此数字转换为字符串并使用 .contains 搜索此字符串() 方法效率更高?
我的代码:
boolean zero(int n) {
if(n == 0)
return true;
while(n > 0) {
if(n % 10 == 0)
return true;
n = n/10;
}
return false;
}
如有任何帮助,我们将不胜感激。
嗯,实际上,想一想字符串,每个数字,是如何 'created':除以 10 的模数。所以 int-to-String 转换实际上会完成与您正在做的相同的任务.
这是 Integer.getChars()
的源代码,这是通过 Integer.toString()
调用的,以及一些其他缓冲区管理:
static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
sign = '-';
i = -i;
}
// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
buf [--charPos] = digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}
如您所见,它使用比 65536 更大的数字,并改进了除法转换循环。对于较低的数字(或者一旦原始数字被削减),有一些大量的优化(位移和字节掩码)并继续进行。 除法通常成本更高,比位移慢 20 到 60 倍。所以最后一部分真的很快。但这只是5位数,那会有多大影响呢?
还要考虑内存管理。 JVM 可能 运行 如果您的系统在所有内核上保持 运行ning 100%,并且当(如果)可能必须进行垃圾收集时,GC 引发的 'forced'暂停可能会消除所有速度优势。 (测试这个应该是分分钟的长期测试)。
您也可以考虑将 problem/tasks 拆分到多个线程中。最简单的方法是使用 java 1.8-new 流。或者你有自己的 parallelizer/splitter 和自己的任务 arrays/queues。可能几乎是任务速度的 n 倍,n 是您可以使用的 CPU 个核心数。
正如其他人所说,实际上最好自己测试速度。 最好写一个 运行 大约 10 秒的测试。这足够长,可以为您提供稳定的估算和启动 JIT 优化,也足够短,不会让您感到厌烦。
另一方面,通常最好以明显的、不神秘的、易于维护的方式解决问题。因此,如果我必须实施它,我会进行测试,如果差异小于 5 倍,我会坚持只使用数字。没有附加条件:-D