为什么有警告不要使用 system.cmp[string] 进行 Nim 字符串比较
Why is there a warning not to use system.cmp[string] for Nim string comparison
在Nim标准库中有一个warning:
sort(myIntArray, system.cmp[int])
# do not use cmp[string] here as we want to use the specialized
# overload:
sort(myStrArray, system.cmp)
谁能对此提供更多解释?
我试过的
- 查看源代码
听起来可能有两种排序实现,一种是普通实现,一种是专门用于比较字符串的实现,但是查看源代码here我找不到任何这样的专门化。
- 使用编译器进行实验
我试过编写以下程序:
import algorithm
var strArray: array[4,string] = ["a","ab","abcd","abc"]
sort(strArray, system.cmp[string])
# sort(strArray, system.cmp)
for x in strArray:
echo x
并尝试了两种比较方式。但是,当我比较生成的 C 代码时,似乎没有任何显着差异。 fc 的输出如下所示,但在我看来这只是不重要的更改:
Comparing files NIMCACHE\testsorta.c and NIMCACHE\TESTSORT.C
***** NIMCACHE\testsorta.c
typedef struct {
N_NIMCALL_PTR(NI, ClPrc) (NimStringDesc* x_91042, NimStringDesc* y_91044, void*
ClEnv);
void* ClEnv;
} TY91048;
typedef N_CLOSURE_PTR(NI, TMP153) (NimStringDesc* x_91025, NimStringDesc* y_9102
7, void* ClEnv);
struct tcell44933 {
***** NIMCACHE\TESTSORT.C
typedef struct {
N_NIMCALL_PTR(NI, ClPrc) (NimStringDesc* x_91054, NimStringDesc* y_91056, void*
ClEnv);
void* ClEnv;
} TY91060;
typedef N_CLOSURE_PTR(NI, TMP153) (NimStringDesc* x_91037, NimStringDesc* y_9103
9, void* ClEnv);
struct tcell44933 {
*****
***** NIMCACHE\testsorta.c
N_NIMCALL(void, genericAssign)(void* dest, void* src, TNimType* mt);
N_NIMCALL(void, sort_91029)(NimStringDesc** a_91037, NI a_91037Len0, TY91048 cmp
_91047, NU8 order_91050);
N_NIMCALL(void, merge_91090)(NimStringDesc** a_91098, NI a_91098Len0, NimStringD
esc** b_91106, NI b_91106Len0, NI lo_91110, NI
m_91112, NI hi_91114, TY91048 cmp_91122, NU8 order_91125);
N_NIMCALL(NI, cmp_4517)(NimStringDesc* x, NimStringDesc* y);
N_NIMCALL(NimStringDesc*, copyStringRC1)(NimStringDesc* src);
***** NIMCACHE\TESTSORT.C
N_NIMCALL(void, genericAssign)(void* dest, void* src, TNimType* mt);
N_NIMCALL(NI, cmp_91024)(NimStringDesc* x_91028, NimStringDesc* y_91030);
N_NIMCALL(void, sort_91041)(NimStringDesc** a_91049, NI a_91049Len0, TY91060 cmp
_91059, NU8 order_91062);
N_NIMCALL(void, merge_91102)(NimStringDesc** a_91110, NI a_91110Len0, NimStringD
esc** b_91118, NI b_91118Len0, NI lo_91122, NI
m_91124, NI hi_91126, TY91060 cmp_91134, NU8 order_91137);
N_NIMCALL(NimStringDesc*, copyStringRC1)(NimStringDesc* src);
*****
***** NIMCACHE\testsorta.c
NIM_EXTERNC N_NOINLINE(void, testsortInit)(void) {
TY91048 LOC1;
nimfr("testsort", "testsort.nim")
***** NIMCACHE\TESTSORT.C
NIM_EXTERNC N_NOINLINE(void, testsortInit)(void) {
TY91060 LOC1;
nimfr("testsort", "testsort.nim")
*****
***** NIMCACHE\testsorta.c
memset((void*)(&LOC1), 0, sizeof(LOC1));
LOC1.ClPrc = ((TMP153) (cmp_4517)); LOC1.ClEnv = NIM_NIL;
sort_91029(strarray_91015, 4, LOC1, ((NU8) 1));
{
***** NIMCACHE\TESTSORT.C
memset((void*)(&LOC1), 0, sizeof(LOC1));
LOC1.ClPrc = ((TMP153) (cmp_91024)); LOC1.ClEnv = NIM_NIL;
sort_91041(strarray_91015, 4, LOC1, ((NU8) 1));
{
*****
Compare proc for strings. More efficient than the generic version.
这就是区别。 cmp(s1, s2)
比 cmp[string](s1, s2)
更有效率。
您在生成的代码中看不到任何差异的原因是因为一个版本 cmp(string, string)
变成了 C 函数,而另一个版本将泛型实例化为 cmp[string](string, string)
变成了一个C 函数,并且这些函数的签名完全相同。您应该在这些函数的主体中寻找差异,它们应该在 system.c
.
中
在Nim标准库中有一个warning:
sort(myIntArray, system.cmp[int])
# do not use cmp[string] here as we want to use the specialized
# overload:
sort(myStrArray, system.cmp)
谁能对此提供更多解释?
我试过的
- 查看源代码
听起来可能有两种排序实现,一种是普通实现,一种是专门用于比较字符串的实现,但是查看源代码here我找不到任何这样的专门化。
- 使用编译器进行实验
我试过编写以下程序:
import algorithm
var strArray: array[4,string] = ["a","ab","abcd","abc"]
sort(strArray, system.cmp[string])
# sort(strArray, system.cmp)
for x in strArray:
echo x
并尝试了两种比较方式。但是,当我比较生成的 C 代码时,似乎没有任何显着差异。 fc 的输出如下所示,但在我看来这只是不重要的更改:
Comparing files NIMCACHE\testsorta.c and NIMCACHE\TESTSORT.C
***** NIMCACHE\testsorta.c
typedef struct {
N_NIMCALL_PTR(NI, ClPrc) (NimStringDesc* x_91042, NimStringDesc* y_91044, void*
ClEnv);
void* ClEnv;
} TY91048;
typedef N_CLOSURE_PTR(NI, TMP153) (NimStringDesc* x_91025, NimStringDesc* y_9102
7, void* ClEnv);
struct tcell44933 {
***** NIMCACHE\TESTSORT.C
typedef struct {
N_NIMCALL_PTR(NI, ClPrc) (NimStringDesc* x_91054, NimStringDesc* y_91056, void*
ClEnv);
void* ClEnv;
} TY91060;
typedef N_CLOSURE_PTR(NI, TMP153) (NimStringDesc* x_91037, NimStringDesc* y_9103
9, void* ClEnv);
struct tcell44933 {
*****
***** NIMCACHE\testsorta.c
N_NIMCALL(void, genericAssign)(void* dest, void* src, TNimType* mt);
N_NIMCALL(void, sort_91029)(NimStringDesc** a_91037, NI a_91037Len0, TY91048 cmp
_91047, NU8 order_91050);
N_NIMCALL(void, merge_91090)(NimStringDesc** a_91098, NI a_91098Len0, NimStringD
esc** b_91106, NI b_91106Len0, NI lo_91110, NI
m_91112, NI hi_91114, TY91048 cmp_91122, NU8 order_91125);
N_NIMCALL(NI, cmp_4517)(NimStringDesc* x, NimStringDesc* y);
N_NIMCALL(NimStringDesc*, copyStringRC1)(NimStringDesc* src);
***** NIMCACHE\TESTSORT.C
N_NIMCALL(void, genericAssign)(void* dest, void* src, TNimType* mt);
N_NIMCALL(NI, cmp_91024)(NimStringDesc* x_91028, NimStringDesc* y_91030);
N_NIMCALL(void, sort_91041)(NimStringDesc** a_91049, NI a_91049Len0, TY91060 cmp
_91059, NU8 order_91062);
N_NIMCALL(void, merge_91102)(NimStringDesc** a_91110, NI a_91110Len0, NimStringD
esc** b_91118, NI b_91118Len0, NI lo_91122, NI
m_91124, NI hi_91126, TY91060 cmp_91134, NU8 order_91137);
N_NIMCALL(NimStringDesc*, copyStringRC1)(NimStringDesc* src);
*****
***** NIMCACHE\testsorta.c
NIM_EXTERNC N_NOINLINE(void, testsortInit)(void) {
TY91048 LOC1;
nimfr("testsort", "testsort.nim")
***** NIMCACHE\TESTSORT.C
NIM_EXTERNC N_NOINLINE(void, testsortInit)(void) {
TY91060 LOC1;
nimfr("testsort", "testsort.nim")
*****
***** NIMCACHE\testsorta.c
memset((void*)(&LOC1), 0, sizeof(LOC1));
LOC1.ClPrc = ((TMP153) (cmp_4517)); LOC1.ClEnv = NIM_NIL;
sort_91029(strarray_91015, 4, LOC1, ((NU8) 1));
{
***** NIMCACHE\TESTSORT.C
memset((void*)(&LOC1), 0, sizeof(LOC1));
LOC1.ClPrc = ((TMP153) (cmp_91024)); LOC1.ClEnv = NIM_NIL;
sort_91041(strarray_91015, 4, LOC1, ((NU8) 1));
{
*****
Compare proc for strings. More efficient than the generic version.
这就是区别。 cmp(s1, s2)
比 cmp[string](s1, s2)
更有效率。
您在生成的代码中看不到任何差异的原因是因为一个版本 cmp(string, string)
变成了 C 函数,而另一个版本将泛型实例化为 cmp[string](string, string)
变成了一个C 函数,并且这些函数的签名完全相同。您应该在这些函数的主体中寻找差异,它们应该在 system.c
.