Professional Documents
Culture Documents
personalizacin de AutoCAD
Actualmente AutoCAD permite su personalizacin mediante cuatro
lenguajes de programacin que pueden ser usados para realizar
desde tareas simples, repetitivas y con mucha frecuencia tediosas,
hasta complejas aplicaciones especializadas en cualquier campo del
diseo grfico asistido por computadora.
Estos cuatro lenguajes incluyen AutoLISP, Visual LISP, Visual Basic
(VBA) y C++ (ObjectARX/ObjectDBX). Visual Lisp es el hermano
mayor de AutoLisp y aunque podemos decir que engloba a AutoLISP
prefiero tratarlos como lenguajes separados y entender Visual LISP
como el lenguaje AutoLISP con extensiones ActiveX (u OLE, que es lo
mismo).
Ninguno de estos cuatro lenguajes es mejor ni peor que otro,
sencillamente son adecuados o no para la realizacin de una tarea
concreta. No obstante, personalmente la velocidad de ejecucin de
los algoritmos que implemento es una cuestin que me preocupa
mucho. Y aunque influye mucho ms sobre el rendimiento la forma
de implementar, el propio diseo del lenguaje tambin tiene un peso
especfico considerable.
Con el fin de comparar la velocidad de ejecucin de estos cuatro
lenguajes he preparado una sencilla prueba que permita realizar esta
comparacin. Aunque ya supongo cualitativamente los resultados de
la prueba, tengo curiosidad por cuantificarlos. Por ello he preparado la
siguiente prueba.
Ejecutar una rutina que dibuje un nmero determinado de crculos
concntricos y al finalizar muestre su tiempo de ejecucin. Este sera
ms o menos su pseudocdigo :
funcion DibujaCirculo(centro, radio)
{
AadeEntidadCirculoalModeloEspacio(centro, radio)
}
funcion concir()
{
solicitarepeticiones(n)
tomatiempoinicial()
repite n
{
DibujaCirculo(centro, radio)
radio = radio + 0.001
}
tomatiempofinal()
}
presentatiempoejecucion()
(princ)
)
;liberar
(setq *MODELSPACE* nil)
(princ)
)
With centro
'
centerPoint(0) = .X
centerPoint(1) = .Y
centerPoint(2) = .Z
'
End With
'
'/* usaremos vinculacin temprana para optimizar
'
la velocidad de ejecucin */
Dim objCircle As AcadCircle
'
Set objCircle = ThisDrawing.ModelSpace.AddCircle(centerPoint,
radio)
'
End Sub
'
Public Sub concirVBA()
'
On Error Resume Next
'
Dim centro
As New AcPoint
Dim radio
As Double
Dim n
As Integer
Dim t0
As Double
Dim tf
As Double
Dim i
As Integer
Dim tiempo
As Double
Dim promptStr
As String
'
'/* mensaje de consola */
ActiveDocument.Utility.Prompt (vbCrLf & "Prueba de velocidad
[VBA].")
'
'/* inicializar las variables */
'
With centro
'
.X = 0#
.Y = 0#
.Z = 0#
'
End With
'
radio = 1#
'
'/* solicitar el nmero de repeticiones */
'
Err.Clear
'
n = ActiveDocument.Utility.GetInteger(vbCrLf & "Nmero de
repeticiones : ")
'
'/* chequear si se cancel */
If (Err.Number = -2147352567) Then
'
ActiveDocument.Utility.Prompt ("*Cancel*" & vbCrLf)
'
Exit Sub
'
End If
'
If (n <= 0) Then
'
n = 1000
'
End If
'
ActiveDocument.Utility.Prompt (vbCrLf & "Realizando la prueba para
" & _
n & " repeticiones ..." & vbCrLf)
'
'/* tomar el tiempo inicial */
t0 = ActiveDocument.GetVariable("DATE")
'
'/* repetir n veces ... */
For i = 1 To n
'
Call DibujaCirculo(centro, radio)
'
radio = radio + 0.001
'
Next i
'
'/* tomar el tiempo final */
tf = ActiveDocument.GetVariable("DATE")
'
'/* calcular los milisegundos */
tiempo = (tf - t0) * 86400000#
'
promptStr = vbCrLf & "Tiempo de ejecucin de la prueba = " & _
CLng(tiempo) & " ms, con " & n & " repeticiones." &
vbCrLf
'
ActiveDocument.Utility.Prompt promptStr
'
'/* liberar */
'
Set centro = Nothing
'
End Sub
C++ (ObjectARX)
Acad::ErrorStatus appendEntityToModelSpaceBlockTableRecord(AcDbEntity
*pEntity, AcDbObjectId& ID)
{
Acad::ErrorStatus
es;
AcDbBlockTable *pBlockTable;
// obtener un puntero a la BlockTableRecord Modelo Espacio
es = acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
if (es != Acad::eOk)
return es;
AcDbBlockTableRecord *pBlockTableRecord;
es = pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close();
if (es != Acad::eOk)
return es;
// aadir la entidad a la BlockTableRecord
es = pBlockTableRecord->appendAcDbEntity(ID, pEntity);
// se cierra la entidad
pEntity->close();
pBlockTableRecord->close();
}
return es;
catch(const std::bad_alloc&)
{
acdbFail("\nError de asignacin de memoria
[DibujaCirculo].");
return;
}
AcDbObjectId ID;
// ... y aadirla a la base de datos de AutoCAD
if
(appendEntityToModelSpaceBlockTableRecord((AcDbEntity*)pCircle, ID) !=
Acad::eOk)
{
if (pCircle)
{
delete pCircle;
}
acdbFail("\nError al aadir la entidad a la Base de
Datos [DibujaCirculo].");
}
return;
return;
}
// This is command 'CONCIRARX'
void TPLDPruebasconcirarx()
{
// mensaje de consola
radio += 0.001;
return;
}
Tabla de resultados
Pues aqu est el resultado de la prueba hecho con un P4 a 1.7GHz
con 256MB de RAM y bajo AutoCAD 2000. Antes de presentar la tabla
he de decir que personalmente me esperaba lo siguiente.
AutoLISP sera es ms lento de todos, seguido muy de cerca por el
formato FAS. Posteriormente crea que el formato VLX ira muy a la
par con VBA y no hubiera sabido decidirme entre uno y otro para la
tercera posicin. Y por ltimo me esperaba una victoria aplastante de
ObjectARX. Pero hay sorpresas :
REPETICIONES
Tiempo en milisegundos
LSP
FAS
VLX
VBA
ARX
50
10
10
19
10
500
210
169
221
120
40
1000
431
340
440
250
90
2500
1061
871
1080
631
220
5000
2113
1811
2172
1282
431
10000
4126
3925
4336
2564
871