Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Using+Tcl_ListObj+and+his+friends?V=3
QUERY_STRINGV=3
CONTENT_TYPE
DOCUMENT_URI/revision/Using+Tcl_ListObj+and+his+friends
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.127.34
REMOTE_PORT19318
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.149.28.145
HTTP_CF_RAY887327673bafe133-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_REFERERhttp://wiki.tcl.tk/revision/Using+Tcl%5FListObj+and+his+friends?V=3
HTTP_CF_CONNECTING_IP3.149.28.145
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

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