我花了几个小时试图找出为什么我的排序算法的Java版本比递归合并排序慢两倍,因为C和C++版本的速度提高了40-50%.我一直在删除越来越多的代码,直到我将所有代码都删除到一个简单的循环并合并,但它仍然是两倍慢.为什么这只在Java中这么慢?
作为参考,这是自下而上的合并排序可能是这样的:
public static <T> void sort(T[] a, T[] aux, Comparator<T> comp) {
int N = a.length;
for (int n = 1; n < N; n = n+n)
for (int i = 0; i < N-n; i += n+n)
merge(a, aux, i, i+n-1, Math.min(i+n+n-1, N-1), comp);
}
Run Code Online (Sandbox Code Playgroud)
这是递归版本:
public static <T> void sort(T[] a, T[] aux, int lo, int hi, Comparator<T> comp) {
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid, comp); …
Run Code Online (Sandbox Code Playgroud) 这纯粹是为了满足我自己的好奇心,但为什么函数和类型只能在代码中先前定义的那些中解析,而不是在同一范围内的任何地方?
有时它会在函数需要相互调用时显示:
void foo(int depth) { bar(depth + 2); }
void bar(int depth) { if (depth > 0) foo(depth - 3); }
Run Code Online (Sandbox Code Playgroud)
你需要在foo之前移动bar,或者事先声明bar:
void bar(int);
void foo(int depth) { bar(depth + 2); }
void bar(int depth) { if (depth > 0) foo(depth - 3); }
Run Code Online (Sandbox Code Playgroud)
在更复杂的示例中,您可能需要查看#include树和#ifndef警卫,以找出您的代码无法识别某个其他文件中定义的函数或类型的原因,如果您已经知道您应该检查该代码.
然后当然有这个经典:
typedef struct {
Node *next;
} Node;
Run Code Online (Sandbox Code Playgroud)
你需要知道这是可能的:
typedef struct Node {
struct Node *next;
} Node;
Run Code Online (Sandbox Code Playgroud)
......但显然许多人不这样做,他们只是到处都使用'void*'或'struct Node'.
那么,这些编译器也没有解决这个问题的原因吗?我可以理解预处理器只是向后检查,因为事情可以是#undefined,但是一旦声明了类型或函数,它就会存在并且不能被后来的定义重载.
这是出于历史原因,它们在首次开发时可用的技术有限吗?或者是否存在一些我遗漏的逻辑歧义?
我在C中的#define语句中有可选参数的问题,或者更具体地说是gcc 4.2:
bool func1(bool tmp) { return false; }
void func2(bool tmp, bool tmp2) {}
#define CALL(func, tmp, ...) func(tmp, ##__VA_ARGS__)
int main() {
// this compiles
CALL(func2, CALL(func1, false), false);
// this fails with: Implicit declaration of function 'CALL'
CALL(func2, false, CALL(func1, false));
}
Run Code Online (Sandbox Code Playgroud)
这显然是一个人为的例子,但确实显示了问题.有谁知道我怎么能得到正确的"解决"的可选参数?
附加信息:如果我删除##
之前__VA_ARGS__
,并执行以下操作:
bool func2(bool tmp, bool tmp2) { return false; }
#define CALL(func, tmp, ...) func(tmp, __VA_ARGS__)
int main() {
CALL(func2, false, CALL(func2, false, false));
}
Run Code Online (Sandbox Code Playgroud)
编译,但它不再适用零参数,因为它将解决 func(tmp, ) …
当我尝试执行此操作时:
#include<stdio.h>
int byteland(int a)
{
int e,f,g;
if ((a/2 + a/3 + a/4) < a)
return a;
else
{
e = byteland(a/2);
f = byteland(a/3);
g = byteland(a/4);
return e + f + g;
}
}
int main()
{
int a, b;
scanf("%d", &a);
b = byteland(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到分段错误(核心转储).有解决方案吗