我的目标是迭代一个列表以找出我的值对应的内容并将类型添加到另一个列表中。为此,我按照
Tcl
中的步骤进行操作。
proc TCL_dataType {dataList} {
set Tag {}
foreach value $dataList {
if {[string is double -strict $value]} {
lappend Tag "N"
} elseif {$value eq "null"} {
lappend Tag "_"
} else {
lappend Tag "S"
}
}
return $Tag
}
在
C
方面,我尝试做同样的事情:
int C_dataType (Tcl_Interp* interp Tcl_Obj* data) {
Tcl_Obj **dataList;
int count;
double d;
if (Tcl_ListObjGetElements(interp, data, &count, &dataList) != TCL_OK) {
return TCL_ERROR;
}
Tcl_Obj *Tag = Tcl_NewListObj (0,NULL);
Tcl_Obj* s = Tcl_NewStringObj("S", 1);
Tcl_Obj* n = Tcl_NewStringObj("N", 1);
Tcl_Obj* null = Tcl_NewStringObj("_", 1);
for (int i = 0; i < count; ++i) {
if (Tcl_GetDoubleFromObj(interp, dataList[i], &d) == TCL_OK) {
Tcl_ListObjAppendElement(interp, Tag, n);
} else if (!strcmp(Tcl_GetString(dataList[i]), "null")) {
Tcl_ListObjAppendElement(interp, Tag, null);
} else {
Tcl_ListObjAppendElement(interp, Tag, s);
}
}
Tcl_SetObjResult(interp, Tag);
return TCL_OK;
}
我的方法在
C
方面可能不正确,但如果我测量执行时间,我的 C
代码会慢 5 倍。
proc randomValues {len} {
set l {10 null foo bar}
set randomList {}
for {set i 0} {$i < $len} {incr i} {
set index [expr {int(rand() * 4)}]
lappend randomList [lindex $l $index]
}
return $randomList
}
set myRandomList [randomValues 10000]
# time measure
puts [time {C_dataType $myRandomList} 10] ; # 4921.3521 microseconds per iteration
puts [time {TCL_dataType $myRandomList} 10] ; # 986.0601 microseconds per iteration
'Tcl_GetDoubleFromObj'似乎花费了我的时间,所以我通过删除这个
C
函数以及我的 Tcl
程序中的 'string is double -strict xxx' 来进行测试以比较相同的东西,在这里恰恰相反。
C
方面,我希望知道变量的类型...但我不知道如何在不使用此函数的情况下控制每个 Tcl 对象。
尝试将 NULL 用于 interp 传递给 Tcl_GetDoubleFromObj。我怀疑时间花在了设置一个永远不会被使用的错误结果上。