Error processing request
Parameters
CONTENT_LENGTH | 0 |
REQUEST_METHOD | GET |
REQUEST_URI | /revision/Using+Tcl_ListObj+and+his+friends?V=3 |
QUERY_STRING | V=3 |
CONTENT_TYPE | |
DOCUMENT_URI | /revision/Using+Tcl_ListObj+and+his+friends |
DOCUMENT_ROOT | /var/www/nikit/nikit/nginx/../docroot |
SCGI | 1 |
SERVER_PROTOCOL | HTTP/1.1 |
HTTPS | on |
REMOTE_ADDR | 172.70.127.34 |
REMOTE_PORT | 19318 |
SERVER_PORT | 4443 |
SERVER_NAME | wiki.tcl-lang.org |
HTTP_HOST | wiki.tcl-lang.org |
HTTP_CONNECTION | Keep-Alive |
HTTP_ACCEPT_ENCODING | gzip, br |
HTTP_X_FORWARDED_FOR | 3.149.28.145 |
HTTP_CF_RAY | 887327673bafe133-ORD |
HTTP_X_FORWARDED_PROTO | https |
HTTP_CF_VISITOR | {"scheme":"https"} |
HTTP_ACCEPT | */* |
HTTP_USER_AGENT | Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected]) |
HTTP_REFERER | http://wiki.tcl.tk/revision/Using+Tcl%5FListObj+and+his+friends?V=3 |
HTTP_CF_CONNECTING_IP | 3.149.28.145 |
HTTP_CDN_LOOP | cloudflare |
HTTP_CF_IPCOUNTRY | US |
Body
Error
Unknow state transition: LINE -> END
-code
1
-level
0
-errorstack
INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {Using Tcl_ListObj and his friends} {This page compares [lsort] with some alternative optimized commands to sort a integer list.
The purpose is to compare different ways to handle [Tcl_ListObj]'s fast.
The sort is not so much of interest, but more the performance handling a list in C(++).
**Code**
----
======
#include <tcl.h>
#include "Run.h"
#include <vector>
#include <algorithm>
#include <sstream>
void sort(std::vector<int>& vec)
{
//std::sort(vec.begin(), vec.end());
}
void sort(int* begin, int* end)
{
//std::sort<int*>(begin,end);
}
int Run_ObjCmd1(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd3(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd4(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd5(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.0", 0) == NULL) {
return TCL_ERROR;
}
if (Tcl_PkgProvide(interp, "run", "0.1") != TCL_OK) {
return TCL_ERROR;
}
// use Tcl_ListObjIndex
Tcl_CreateObjCommand(interp, "::run::run1", Run_ObjCmd1,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use Tcl_ListObjGetElements
Tcl_CreateObjCommand(interp, "::run::run2", Run_ObjCmd2,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use Tcl_SetResult (string interface) instead of Tcl_SetObjResult
// (rest run2)
Tcl_CreateObjCommand(interp, "::run::run3", Run_ObjCmd3,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use std::vector<int>::reserve
// (rest run2)
Tcl_CreateObjCommand(interp, "::run::run4", Run_ObjCmd4,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use int[] instead of std::vector
Tcl_CreateObjCommand(interp, "::run::run5", Run_ObjCmd5,
NULL, (Tcl_CmdDeleteProc*)NULL);
return TCL_OK;
}
int Run_ObjCmd5(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
int* pInt = new int[length];
int* pIter = pInt;
for (int i = 0; i < length; ++i,++elem,++pIter)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
{
delete[] pInt;
return TCL_ERROR;
}
*pIter = x;
}
sort(pInt,&pInt[length]);
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
pIter = pInt;
for (int i = 0; i < length; ++i,++pIter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*pIter));
}
delete[] pInt;
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
int Run_ObjCmd4(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
sort_int.reserve(static_cast<std::vector<int>::size_type>(length));
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
for (int i = 0; i < length; ++i,++elem)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*iter));
}
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
int Run_ObjCmd3(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
for (int i = 0; i < length; ++i,++elem)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_ResetResult(interp);
std::stringstream list_str;
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
list_str << " " << *iter;
}
Tcl_SetResult(interp, const_cast<char *>(list_str.str().c_str()), TCL_VOLATILE);
return TCL_OK;
}
int Run_ObjCmd2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
for (int i = 0; i < length; ++i,++elem)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*iter));
}
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
int Run_ObjCmd1(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
Tcl_Obj* elem;
int x;
for (int i = 0; i < length; ++i)
{
if (Tcl_ListObjIndex(interp, objv[1], i, &elem) != TCL_OK)
return TCL_ERROR;
if (Tcl_GetIntFromObj(interp, elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*iter));
}
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
======
**Script**
----
======
lappend auto_path .
package require run
proc GetBigIntList {n} {
set ret [list]
set i 0
while {$i < $n} {
lappend ret [expr {int(rand()*100)}]
incr i
}
return $ret
}
proc mycall {proc_name l} {
puts "\t $proc_name [time {$proc_name $l} 50]"
}
foreach n {10 100 100000 10000000} {
set l [GetBigIntList $n]
puts "n = $n:"
foreach p {::run::run5 ::run::run4 ::run::run3 ::run::run2 ::run::run1} {
mycall $p $l
}
puts "\t lsort [time {lsort $l} 50]"
puts "\t lsort [time {lsort -integer $l} 50]"
puts ""
}
=====
**Results (with sort)**
----
**Results (without sort)**
----
----
!!!!!!
%| [Category Example] | [Category Performance] | [Category Tcl Library] |%
!!!!!!} regexp2} CALL {my render {Using Tcl_ListObj and his friends} {This page compares [lsort] with some alternative optimized commands to sort a integer list.
The purpose is to compare different ways to handle [Tcl_ListObj]'s fast.
The sort is not so much of interest, but more the performance handling a list in C(++).
**Code**
----
======
#include <tcl.h>
#include "Run.h"
#include <vector>
#include <algorithm>
#include <sstream>
void sort(std::vector<int>& vec)
{
//std::sort(vec.begin(), vec.end());
}
void sort(int* begin, int* end)
{
//std::sort<int*>(begin,end);
}
int Run_ObjCmd1(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd3(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd4(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_ObjCmd5(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[]);
int Run_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.0", 0) == NULL) {
return TCL_ERROR;
}
if (Tcl_PkgProvide(interp, "run", "0.1") != TCL_OK) {
return TCL_ERROR;
}
// use Tcl_ListObjIndex
Tcl_CreateObjCommand(interp, "::run::run1", Run_ObjCmd1,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use Tcl_ListObjGetElements
Tcl_CreateObjCommand(interp, "::run::run2", Run_ObjCmd2,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use Tcl_SetResult (string interface) instead of Tcl_SetObjResult
// (rest run2)
Tcl_CreateObjCommand(interp, "::run::run3", Run_ObjCmd3,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use std::vector<int>::reserve
// (rest run2)
Tcl_CreateObjCommand(interp, "::run::run4", Run_ObjCmd4,
NULL, (Tcl_CmdDeleteProc*)NULL);
// use int[] instead of std::vector
Tcl_CreateObjCommand(interp, "::run::run5", Run_ObjCmd5,
NULL, (Tcl_CmdDeleteProc*)NULL);
return TCL_OK;
}
int Run_ObjCmd5(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
int* pInt = new int[length];
int* pIter = pInt;
for (int i = 0; i < length; ++i,++elem,++pIter)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
{
delete[] pInt;
return TCL_ERROR;
}
*pIter = x;
}
sort(pInt,&pInt[length]);
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
pIter = pInt;
for (int i = 0; i < length; ++i,++pIter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*pIter));
}
delete[] pInt;
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
int Run_ObjCmd4(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
sort_int.reserve(static_cast<std::vector<int>::size_type>(length));
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
for (int i = 0; i < length; ++i,++elem)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*iter));
}
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
int Run_ObjCmd3(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
for (int i = 0; i < length; ++i,++elem)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_ResetResult(interp);
std::stringstream list_str;
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
list_str << " " << *iter;
}
Tcl_SetResult(interp, const_cast<char *>(list_str.str().c_str()), TCL_VOLATILE);
return TCL_OK;
}
int Run_ObjCmd2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
Tcl_Obj** elem;
int x;
if (Tcl_ListObjGetElements(interp, objv[1], &length, &elem) != TCL_OK)
return TCL_ERROR;
for (int i = 0; i < length; ++i,++elem)
{
if (Tcl_GetIntFromObj(interp, *elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*iter));
}
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
int Run_ObjCmd1(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj*CONST objv[])
{
if (objc != 2)
{
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
int length;
if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK)
return TCL_ERROR;
if (!length)
return TCL_OK;
std::vector<int> sort_int;
Tcl_Obj* elem;
int x;
for (int i = 0; i < length; ++i)
{
if (Tcl_ListObjIndex(interp, objv[1], i, &elem) != TCL_OK)
return TCL_ERROR;
if (Tcl_GetIntFromObj(interp, elem, &x) != TCL_OK)
return TCL_ERROR;
sort_int.push_back(x);
}
sort(sort_int);
std::vector<int>::const_iterator iter;
Tcl_Obj* listPtr = Tcl_NewListObj(0,NULL);
for (iter = sort_int.begin(); iter != sort_int.end(); ++iter)
{
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(*iter));
}
Tcl_SetObjResult(interp,listPtr);
return TCL_OK;
}
======
**Script**
----
======
lappend auto_path .
package require run
proc GetBigIntList {n} {
set ret [list]
set i 0
while {$i < $n} {
lappend ret [expr {int(rand()*100)}]
incr i
}
return $ret
}
proc mycall {proc_name l} {
puts "\t $proc_name [time {$proc_name $l} 50]"
}
foreach n {10 100 100000 10000000} {
set l [GetBigIntList $n]
puts "n = $n:"
foreach p {::run::run5 ::run::run4 ::run::run3 ::run::run2 ::run::run1} {
mycall $p $l
}
puts "\t lsort [time {lsort $l} 50]"
puts "\t lsort [time {lsort -integer $l} 50]"
puts ""
}
=====
**Results (with sort)**
----
**Results (without sort)**
----
----
!!!!!!
%| [Category Example] | [Category Performance] | [Category Tcl Library] |%
!!!!!!}} CALL {my revision {Using Tcl_ListObj and his friends}} CALL {::oo::Obj747482 process revision/Using+Tcl_ListObj+and+his+friends} CALL {::oo::Obj747480 process}
-errorcode
NONE
-errorinfo
Unknow state transition: LINE -> END
while executing
"error $msg"
(class "::Wiki" method "render_wikit" line 6)
invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
(class "::Wiki" method "render" line 8)
invoked from within
"my render $name $C"
(class "::Wiki" method "revision" line 31)
invoked from within
"my revision $page"
(class "::Wiki" method "process" line 56)
invoked from within
"$server process [string trim $uri /]"
-errorline
4