Tcl Source Code

Artifact [3220d49fad]
Login

Artifact 3220d49fad5cbd7d0864279e9557a9d653e97340:

Attachment "None" to ticket [402471ffff] added by pgbaum 2000-11-22 17:17:46.
Speed enhancement of canvas

Despite the use of Tcl_Obj every coordinate of a canvas item
is converted to a string and then to a double value plus
unit.

This patch (6 new lines) speeds up the common case, where the 
coordiante is already a double value without unit. In my 
application (Linux 2.2.17) I get a speed up by a factor of 2!


--- tkObj.orig.c	Tue Nov  7 20:35:43 2000
+++ tkObj.c	Wed Nov  8 19:44:41 2000
@@ -501,48 +501,54 @@
     int units;
     MMRep *mmPtr;
 
-    string = Tcl_GetStringFromObj(objPtr, NULL);
-
-    d = strtod(string, &rest);
-    if (rest == string) {
-	/*
-	 * Must copy string before resetting the result in case a caller
-	 * is trying to convert the interpreter's result to mms.
-	 */
-
-	error:
-	Tcl_AppendResult(interp, "bad screen distance \"", string,
-		"\"", (char *) NULL);
-	return TCL_ERROR;
+    if( objPtr->typePtr == &tclDoubleType ) {
+        /* optimize for speed reasons */
+        Tcl_GetDoubleFromObj( interp, objPtr, &d );
+        units = -1;
+    } else {
+        string = Tcl_GetStringFromObj(objPtr, NULL);
+   
+        d = strtod(string, &rest);
+        if (rest == string) {
+            /*
+             * Must copy string before resetting the result in case a caller
+             * is trying to convert the interpreter's result to mms.
+             */
+   
+            error:
+            Tcl_AppendResult(interp, "bad screen distance \"", string,
+                    "\"", (char *) NULL);
+            return TCL_ERROR;
+        }
+        while ((*rest != '\0') && isspace(UCHAR(*rest))) {
+            rest++;
+        }
+        switch (*rest) {
+        case '\0':
+   	    units = -1;
+   	    break;
+   
+   	case 'c':
+   	    units = 0;
+   	    break;
+   
+   	case 'i':
+   	    units = 1;
+   	    break;
+   
+   	case 'm':
+   	    units = 2;
+   	    break;
+   
+   	case 'p':
+   	    units = 3;
+   	    break;
+   
+   	default:
+   	    goto error;
+       }
     }
-    while ((*rest != '\0') && isspace(UCHAR(*rest))) {
-	rest++;
-    }
-    switch (*rest) {
-	case '\0':
-	    units = -1;
-	    break;
-
-	case 'c':
-	    units = 0;
-	    break;
-
-	case 'i':
-	    units = 1;
-	    break;
-
-	case 'm':
-	    units = 2;
-	    break;
-
-	case 'p':
-	    units = 3;
-	    break;
-
-	default:
-	    goto error;
-    }
-
+   
     /*
      * Free the old internalRep before setting the new one. 
      */