Java 和 C 中的字符串比较性能
String comparision performance in Java and C
我需要测量比较两个字符串的函数的性能。我的任务是用 Java 和 C 编写并比较执行时间。出于测试目的,我生成了一个包含 100000 个随机字符串的 txt 文件,每个字符串从 100 到 200 个字符不等。使用它们我调用比较函数 20'000'000 次。在 Java 中需要大约 500 毫秒,而在 C 中执行时间为 0 毫秒(我在两种语言中对完全相同的数据进行完全相同的测试)。即使我在 C 中将它增加到 20'000'000'000 次调用,它仍然测量 0ms 持续时间。这怎么可能?我错过了什么重要的东西吗?
在Java
中实施
public class StringComparer {
public static boolean compareStrings(String string1, String string2) {
if(string1.length() != string2.length()) {
return false;
}
for (int i = 0; i < string1.length(); i++) {
if(string1.charAt(i) != string2.charAt(i)) {
return false;
}
}
return true;
}
}
C 中的实现
bool string_compare(char* s1, char* s2)
{
int i = 0;
while (s1[i] != NULL && s1[i] == s2[i])
i++;
return s1[i] == s2[i];
}
这是我用来测试C语言性能的代码
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <windows.h>
#define NUMBER_OF_WORDS 100000
#define MAX_WORD_LENGTH 200
long long milliseconds_now() {
static LARGE_INTEGER s_frequency;
BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
if (s_use_qpc) {
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart) / s_frequency.QuadPart;
}
else {
return GetTickCount();
}
}
int main()
{
char* fileName = "tests.txt";
FILE *file = fopen(fileName, "r");
char* words[NUMBER_OF_WORDS];
long long i, j;
for (i = 0; i < NUMBER_OF_WORDS; i++) {
words[i] = (char*)malloc((MAX_WORD_LENGTH + 1) * sizeof(char));
fgets(words[i], MAX_WORD_LENGTH + 1, file);
}
long long repeats = 10000000000 / NUMBER_OF_WORDS;
long long start = milliseconds_now();
for (i = 0; i < repeats; i++)
{
for (j = 0; j < NUMBER_OF_WORDS - 1; j++)
{
;
}
}
long long loopDuration = milliseconds_now() - start;
start = milliseconds_now();
for (i = 0; i < repeats; i++)
{
for (j = 0; j < NUMBER_OF_WORDS - 1; j++)
{
string_compare(words[j], words[j + 1]); //compare different strings
string_compare(words[j], words[j]); //compare the same strings
}
}
long long customFunctionDuration = milliseconds_now() - start;
printf("Loop duration: %lld\n", loopDuration);
printf("Custom function duration: %lld - %lld = %lld ms", customFunctionDuration, loopDuration, customFunctionDuration - loopDuration);
return 0;
}
您的代码的可观察行为与什么都不做的代码完全相同。您需要使字符串比较的结果成为程序可观察行为的一部分,这样它们就不会被优化为空。尝试计算字符串匹配的次数和字符串不匹配的次数并输出该数字。
我需要测量比较两个字符串的函数的性能。我的任务是用 Java 和 C 编写并比较执行时间。出于测试目的,我生成了一个包含 100000 个随机字符串的 txt 文件,每个字符串从 100 到 200 个字符不等。使用它们我调用比较函数 20'000'000 次。在 Java 中需要大约 500 毫秒,而在 C 中执行时间为 0 毫秒(我在两种语言中对完全相同的数据进行完全相同的测试)。即使我在 C 中将它增加到 20'000'000'000 次调用,它仍然测量 0ms 持续时间。这怎么可能?我错过了什么重要的东西吗?
在Java
中实施public class StringComparer {
public static boolean compareStrings(String string1, String string2) {
if(string1.length() != string2.length()) {
return false;
}
for (int i = 0; i < string1.length(); i++) {
if(string1.charAt(i) != string2.charAt(i)) {
return false;
}
}
return true;
}
}
C 中的实现
bool string_compare(char* s1, char* s2)
{
int i = 0;
while (s1[i] != NULL && s1[i] == s2[i])
i++;
return s1[i] == s2[i];
}
这是我用来测试C语言性能的代码
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <windows.h>
#define NUMBER_OF_WORDS 100000
#define MAX_WORD_LENGTH 200
long long milliseconds_now() {
static LARGE_INTEGER s_frequency;
BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
if (s_use_qpc) {
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart) / s_frequency.QuadPart;
}
else {
return GetTickCount();
}
}
int main()
{
char* fileName = "tests.txt";
FILE *file = fopen(fileName, "r");
char* words[NUMBER_OF_WORDS];
long long i, j;
for (i = 0; i < NUMBER_OF_WORDS; i++) {
words[i] = (char*)malloc((MAX_WORD_LENGTH + 1) * sizeof(char));
fgets(words[i], MAX_WORD_LENGTH + 1, file);
}
long long repeats = 10000000000 / NUMBER_OF_WORDS;
long long start = milliseconds_now();
for (i = 0; i < repeats; i++)
{
for (j = 0; j < NUMBER_OF_WORDS - 1; j++)
{
;
}
}
long long loopDuration = milliseconds_now() - start;
start = milliseconds_now();
for (i = 0; i < repeats; i++)
{
for (j = 0; j < NUMBER_OF_WORDS - 1; j++)
{
string_compare(words[j], words[j + 1]); //compare different strings
string_compare(words[j], words[j]); //compare the same strings
}
}
long long customFunctionDuration = milliseconds_now() - start;
printf("Loop duration: %lld\n", loopDuration);
printf("Custom function duration: %lld - %lld = %lld ms", customFunctionDuration, loopDuration, customFunctionDuration - loopDuration);
return 0;
}
您的代码的可观察行为与什么都不做的代码完全相同。您需要使字符串比较的结果成为程序可观察行为的一部分,这样它们就不会被优化为空。尝试计算字符串匹配的次数和字符串不匹配的次数并输出该数字。