61
High Performance High Performance AutoCAD Programming AutoCAD Programming Autodesk University Autodesk University Class # CP31 Class # CP31 - - 1 1 Dec. 2, 2004 Dec. 2, 2004 Davis Augustine Davis Augustine - - Autodesk, Inc. Autodesk, Inc. daug daug @ @ autodesk autodesk .com .com

High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Embed Size (px)

Citation preview

Page 1: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

High Performance High Performance AutoCAD ProgrammingAutoCAD Programming

Autodesk UniversityAutodesk UniversityClass # CP31Class # CP31--11 Dec. 2, 2004Dec. 2, 2004Davis AugustineDavis Augustine -- Autodesk, Inc.Autodesk, Inc.daugdaug@@autodeskautodesk.com.com

Page 2: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

GoalsGoals

Put Performance in proper perspectivePut Performance in proper perspectiveHear how it’s handled within AutodeskHear how it’s handled within AutodeskLearn how to measure performanceLearn how to measure performanceCompare languages and technologiesCompare languages and technologiesPick up some best practices for codingPick up some best practices for codingUltimately, make your products better and your Ultimately, make your products better and your customers happiercustomers happier

Page 3: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

TopicsTopics

IntroductionIntroductionCompanions to Companions to OptimizationOptimizationBenchmarkingBenchmarkingTimersTimersLanguage Comparisons

Memory UsageMemory UsageAccessing DrawingsAccessing DrawingsProfilingProfilingPerformance CountersPerformance CountersC++ and General C++ and General Techniques

Language ComparisonsTechniques

Page 4: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

One Minute SurveyOne Minute Survey

Developer, Developer, CustomizerCustomizer or CAD Mgr?or CAD Mgr?VB, VB, AutoLispAutoLisp or C++? C#? or C++? C#? AsmAsm??OutOut--ofof--Proc COM Access?Proc COM Access?Custom objects (enablers)?Custom objects (enablers)?Large, Medium or Small App?Large, Medium or Small App?Have performance issues in your app?Have performance issues in your app?Have a performance project or mission?Have a performance project or mission?

Page 5: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Performance in AutoCAD Dev.Performance in AutoCAD Dev.

Performance is considered a featurePerformance is considered a featureReceives attention in every releaseReceives attention in every releaseDedicated Team in AutoCAD DevelopmentDedicated Team in AutoCAD DevelopmentExample of Features Added RecentlyExample of Features Added Recently

Layout caching (avoids Layout caching (avoids regenregen on layout switch)on layout switch)Partial Open (View and layer selection)Partial Open (View and layer selection)Partial Partial RegenRegen (Layer thawing, style changes)(Layer thawing, style changes)XClipXClip (load and (load and regenregen parts of parts of xrefsxrefs))

Page 6: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Intro: User Response TimeIntro: User Response Time

www.www.useituseit.com/papers/.com/papers/responsetimeresponsetime.html.htmlMiller, R. B. (1968). Response time in manMiller, R. B. (1968). Response time in man--computer conversational computer conversational transactions. Proc. AFIPS Fall Joint Computer Conference transactions. Proc. AFIPS Fall Joint Computer Conference Vol. 33Vol. 33, , 267267--277.277.

0.1 second0.1 second is about the limit for having the user feel that the system is is about the limit for having the user feel that the system is reacting instantaneously, ... no special feedback is necessary reacting instantaneously, ... no special feedback is necessary

1.0 second1.0 second is about the limit for the user's flow of thought to stay is about the limit for the user's flow of thought to stay uninterrupted, even though the user will notice the delay. Normauninterrupted, even though the user will notice the delay. Normally, lly, no special feedback is necessary ..., but the user does lose theno special feedback is necessary ..., but the user does lose the feeling feeling of operating directly on the data. of operating directly on the data.

10 seconds10 seconds is about the limit for keeping the user's attention focused ...is about the limit for keeping the user's attention focused .... . For longer delays, users will want to perform other tasks while For longer delays, users will want to perform other tasks while waiting ..., so they should be given feedback indicating when thwaiting ..., so they should be given feedback indicating when the e computer expects to be done.computer expects to be done.

Page 7: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Intro: When to OptimizeIntro: When to Optimize

Design Time vs. Debugging TimeDesign Time vs. Debugging TimeOptimization often adds complexityOptimization often adds complexitywww.www.billharlanbillharlan.com/pub/papers/A_Tirade_Against_the_Cult_o.com/pub/papers/A_Tirade_Against_the_Cult_of_Performance.htmlf_Performance.html“We should forget about small efficiencies, about 97 % of the “We should forget about small efficiencies, about 97 % of the time. Premature Optimization is the root of all evil”time. Premature Optimization is the root of all evil”

Attributed to Donald KnuthAttributed to Donald Knuth“It is easier to optimize correct code than to correct optimized“It is easier to optimize correct code than to correct optimizedcode.” code.” -- HarlanHarlan

Page 8: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Complements to Optimization: Complements to Optimization: FeatureFeature--Based Productivity GainsBased Productivity Gains

Rather than making it faster, offer a new way to Rather than making it faster, offer a new way to do things. Revolution vs. Evolution.do things. Revolution vs. Evolution.www.cadresource.com/r2000/ROI%20White%www.cadresource.com/r2000/ROI%20White%20Paper.htm20Paper.htm

Compares AutoCAD 2000 to R14 and attempts to Compares AutoCAD 2000 to R14 and attempts to quantify productivity gains.quantify productivity gains.New 2000 features include Design Center, MDI, New 2000 features include Design Center, MDI, OPM, Enhanced OPM, Enhanced AutoSnapsAutoSnaps, etc., etc.Estimated productivity gain: 347 % (!)Estimated productivity gain: 347 % (!)

Page 9: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Complements: System TuningComplements: System Tuning

Disk DrivesDisk Drivesdefrag, scandisk/defrag, scandisk/chkdskchkdsk, avoid , avoid SpywareSpywareCan disable Indexing ServiceCan disable Indexing ServiceHKLMHKLM\\SystemSystem\\CurrentControlSetCurrentControlSet\\ControlControl\\FileSyFileSystemstem\\NtfsDisableLastAccessUpdate NtfsDisableLastAccessUpdate ((tweakxptweakxp.com).com)MFT (Master File Table)MFT (Master File Table)Disable 8.3 name creationDisable 8.3 name creationTry compressing NTFS on servers.Try compressing NTFS on servers.Disable Hibernation (frees up space)Disable Hibernation (frees up space)

Page 10: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

More System TuningMore System Tuning

HardwareHardwareMaximize RAM (to avoid swapping)Maximize RAM (to avoid swapping)Look for new 64Look for new 64--bit Pentium systemsbit Pentium systemsGraphics cardsGraphics cards

Control PanelControl PanelProcessor scheduling (Programs Processor scheduling (Programs vsvs Services)Services)Memory Usage (Programs Memory Usage (Programs vsvs System Cache)System Cache)

Page 11: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

BenchmarksBenchmarks

Used for comparing processors, graphics, Used for comparing processors, graphics, compilers, applications, etccompilers, applications, etcMust be repeatableMust be repeatableShould be open and distributableShould be open and distributableShould be clear about what they’re measuringShould be clear about what they’re measuringCan use real world or synthetic dataCan use real world or synthetic dataSan Diego Benchmark was an early oneSan Diego Benchmark was an early one

Page 12: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

CadalystCadalyst BenchmarkBenchmark

Has 2d and 3d ComponentsHas 2d and 3d ComponentsUsed by Used by CadalystCadalyst Magazine to compare Magazine to compare workstations and graphics cardsworkstations and graphics cardshttp://manufacturing.http://manufacturing.cadalystcadalyst.com/manufacturi.com/manufacturing/article/ng/article/articleDetailarticleDetail..jspjsp?id=100182?id=100182May be freely used and modified for personal May be freely used and modified for personal use, but tests or results may not be published use, but tests or results may not be published without their consentwithout their consent

Page 13: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

AUGI BenchmarkAUGI Benchmark

www.www.augiaugi.com/publications/default.asp.com/publications/default.aspJul/Aug 2003 Issue of Jul/Aug 2003 Issue of AugiWorldAugiWorldOriented towards hardware and OS vendorsOriented towards hardware and OS vendorsUsed to compare AutoCAD ReleasesUsed to compare AutoCAD ReleasesCan be customized to test specific commandsCan be customized to test specific commandswww.markcad.com/autocad/a2k2/a2k2_agauge.www.markcad.com/autocad/a2k2/a2k2_agauge.htmhtm

Compares Compares acadacad 2000, 2000i, 2002 and R142000, 2000i, 2002 and R14

Page 14: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

AUGI BM Sample OutputAUGI BM Sample Output

Page 15: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Benchmarking TipsBenchmarking Tips

Disable screen savers, networks, antiDisable screen savers, networks, anti--virus, etcvirus, etcDisable indexing service, Disable indexing service, MsOffice’sMsOffice’s FindFastFindFastDisable AutoSave (Disable AutoSave (savetimesavetime=0)=0)Reboot system before running benchmarkReboot system before running benchmarkOnly compare results on same systemOnly compare results on same systemRun multiple times to get averagesRun multiple times to get averagesWatch out for timer precisionWatch out for timer precisionMay need to disable MDI (May need to disable MDI (sdisdi=1)=1)

Page 16: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timing TestsTiming Tests

Used in benchmarking or ad hoc optimizationUsed in benchmarking or ad hoc optimizationMust be long enough to avoid noiseMust be long enough to avoid noiseShould be repeated multiple timesShould be repeated multiple timesUse a timer with enough precision (not an Use a timer with enough precision (not an hourglass, e.g.)hourglass, e.g.)Try to time as narrow an operation as possible Try to time as narrow an operation as possible (e.g. rule out selection).(e.g. rule out selection).

Page 17: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timers (AutoCAD)Timers (AutoCAD)

Elapsed (Elapsed (akaaka “User”) Timer“User”) TimerAvailable in Available in dbxsdkdbxsdk C++:C++:

AcDbDate d = AcDbDate d = pDbpDb-->>tdusrtimertdusrtimer(); // (); // apiapi callcallAvailable in TIME commandAvailable in TIME command

Command: timeCommand: time

Current time: Friday, November 26, 2004 9:41:02:005Current time: Friday, November 26, 2004 9:41:02:005 AMAMTimes for this drawing:Times for this drawing:

Created: Friday, November 26, 2004 9:40:41:375Created: Friday, November 26, 2004 9:40:41:375 AMAMLast updated: Friday, November 26, 2004 9:40:41:375Last updated: Friday, November 26, 2004 9:40:41:375 AMAMTotal editing time: 0 days 00:00:20:951Total editing time: 0 days 00:00:20:951Elapsed timer (on): 0 days 00:00:20:640Elapsed timer (on): 0 days 00:00:20:640Next automatic save in: <no modifications yet>Next automatic save in: <no modifications yet>

Enter option [Display/ON/OFF/Reset]:Enter option [Display/ON/OFF/Reset]:

Page 18: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timers (AutoCAD)Timers (AutoCAD)

User Timer is TDUSRTIMER User Timer is TDUSRTIMER sysvarsysvarFor deltas, you can also use the DATE For deltas, you can also use the DATE sysvarsysvarReturns value as a Julian DateReturns value as a Julian Date

Julian date is number of days since 1/1/Julian date is number of days since 1/1/--47124712Multiple delta by Multiple delta by secssecs or or msecsmsecs in a dayin a day

((setqsetq start (start (getvargetvar “date”))“date”))< ... do stuff ... >< ... do stuff ... >

((setqsetq delta (delta (-- ((getvargetvar “date”) start))“date”) start))((setqsetq secssecs (* 86400 delta))(* 86400 delta))((princprinc ((strcatstrcat “op took “ (“op took “ (rtosrtos secssecs) “ seconds) “ seconds\\n”))n”))

Page 19: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timers (AutoCAD)Timers (AutoCAD)

CPUTICKS CPUTICKS sysvarsysvarReturns Intel Returns Intel cpu’scpu’s tick count directlytick count directlyIs tied to the chip frequencyIs tied to the chip frequency6464--bit value, harder to work withbit value, harder to work withWatch out for multiple processorsWatch out for multiple processors

Command: Command: cputickscputicks

CPUTICKS = 643530856780.0000 (read only)CPUTICKS = 643530856780.0000 (read only)

Page 20: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timers (Win32)Timers (Win32)

Windows Millisecond TimerWindows Millisecond TimerDWORD DWORD nStartnStart = ::= ::GetTickCountGetTickCount();();

< ... do stuff ... >< ... do stuff ... >DWORD DWORD nElapsedMSecsnElapsedMSecs = ::= ::GetTickCountGetTickCount() () –– nStartnStart;;

Milliseconds since system was bootedMilliseconds since system was booted3232--bit value, wraps at 49.7 daysbit value, wraps at 49.7 daysExposed as “MILLISECS” Exposed as “MILLISECS” sysvarsysvar in AutoCADin AutoCADWatch out for granularity: 10ms or soWatch out for granularity: 10ms or soGetSystemTimeAdjustmentGetSystemTimeAdjustment(); // (); // freq in 100nsfreq in 100nsGetSystemTimeGetSystemTime() has the same granularity issues() has the same granularity issues

Page 21: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timers (Win32)Timers (Win32)

High resolution performance counterHigh resolution performance counter“Should” be okay with multi“Should” be okay with multi--processorsprocessorsIs a divider on the Is a divider on the cpucpu tick counttick countLARGE_INTEGER start, end, freq;LARGE_INTEGER start, end, freq;QueryPerformanceCounterQueryPerformanceCounter(&start);(&start);

< ... do stuff ... >< ... do stuff ... >QueryPerformanceCounterQueryPerformanceCounter(&end);(&end);QueryPerformanceFrequencyQueryPerformanceFrequency(&freq);(&freq);double double dDeltadDelta = (double)(end.= (double)(end.QuadPartQuadPart -- start.start.QuadPartQuadPart););printfprintf("elapsed = %f ("elapsed = %f secssecs\\n", n", dDeltadDelta / (double)freq./ (double)freq.QuadPartQuadPart););

Page 22: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Timers (Visual Basic)Timers (Visual Basic)

timeGetTimetimeGetTime() function in WMM SDK() function in WMM SDKReturns system millisecond timer valueReturns system millisecond timer valueImport from Import from winmmwinmm..dlldll

Timer function returns Timer function returns secssecs since midnightsince midnightTime and Date functions not as usefulTime and Date functions not as useful

Private Declare Function Private Declare Function timeGetTimetimeGetTime Lib "Lib "winmmwinmm..dlldll" () As Long" () As LongDim t1 As LongDim t1 As Long

t1 = t1 = timeGetTimetimeGetTime< ... do stuff ... >< ... do stuff ... >MsgBoxMsgBox "Time in milliseconds = " & "Time in milliseconds = " & timeGetTimetimeGetTime -- t1t1

Page 23: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Language ComparisonsLanguage Comparisons

C++, C++, AutoLISPAutoLISP, COM, VB, VBA and C#, COM, VB, VBA and C#Most ARX and DBX API functionality is Most ARX and DBX API functionality is available in all languagesavailable in all languagesVB/VBA provide ease of development, safetyVB/VBA provide ease of development, safetyC# provides ease of development, safetyC# provides ease of development, safetyC++ provides performance, low level accessC++ provides performance, low level accessAutoLISPAutoLISP provides Eprovides E--OO--D, safety, funkiness!D, safety, funkiness!

Page 24: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Sample: “Count Layers”Sample: “Count Layers”

Search model space for entities on “Layer1”Search model space for entities on “Layer1”Might be useful for partial Might be useful for partial regenregen, or some kind , or some kind of user query toolof user query toolWork involves iteration, getting layer, comparingWork involves iteration, getting layer, comparingLayer compare can be done by name or by idLayer compare can be done by name or by idReport time in Report time in millisecsmillisecs

Page 25: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

VB SampleVB Sample

Out of Proc vs. InOut of Proc vs. In--Proc (ActiveX and VBA)Proc (ActiveX and VBA)OutOfProcFindLayerOutOfProcFindLayer..vbpvbp (in sample files)(in sample files)InProcFindLayerInProcFindLayer..vbpvbpFindLayerVbaFindLayerVba..dvbdvbUsing VB6. I didn’t measure it with VB.NetUsing VB6. I didn’t measure it with VB.Net

Page 26: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

VB SampleVB Sample

Private Sub Private Sub cmdOutofProccmdOutofProc_Click()_Click()LaunchAutoCADLaunchAutoCADDim t1 As LongDim t1 As Longt1 = t1 = timeGetTimetimeGetTimeDim Dim nFoundnFound As LongAs LongDim Dim nEntsnEnts As LongAs LongnFoundnFound = 0= 0nEntsnEnts = 0= 0Dim Dim entent As Object 'As Object 'AcadEntityAcadEntityFor Each For Each entent In In oACADoACAD..ActiveDocumentActiveDocument..ModelSpaceModelSpace

nEntsnEnts = = nEntsnEnts + 1+ 1If If entent.Layer = "Layer1" Then.Layer = "Layer1" Then

nFoundnFound = = nFoundnFound + 1+ 1End IfEnd If

Next Next ententMsgBoxMsgBox nEntsnEnts & " & " entsents. Found Layer1 " & . Found Layer1 " & nFoundnFound & " times. Time in milliseconds = & " times. Time in milliseconds = " & " & timeGetTimetimeGetTime -- t1t1

End SubEnd Sub

Page 27: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

AutoLISPAutoLISP SampleSample

Layer has to be referred to by nameLayer has to be referred to by nameCan use (ssget) to optimizeCan use (ssget) to optimizeCan use Visual Lisp’s automationCan use Visual Lisp’s automationFindLayerFindLayer..lsplsp in sample filesin sample files

Page 28: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

AutoLISPAutoLISP Sample SourceSample Source

((defundefun C:C:findlayerfindlayer ()()((setqsetq layercountlayercount 0)0)((setqsetq entcountentcount 0)0)((setqsetq entadrentadr (entnext))(entnext))(while (while entadrentadr

((setqsetq entpropsentprops ((entgetentget entadrentadr))))((setqsetq layerproplayerprop ((cdrcdr (assoc 8 (assoc 8 entpropsentprops))))))(if (= "Layer1" (if (= "Layer1" layerproplayerprop))

((setqsetq layercountlayercount (1+ (1+ layercountlayercount))))))((setqsetq entcountentcount (1+ (1+ entcountentcount))))((setqsetq entadrentadr ((entnextentnext entadrentadr))))

))((princprinc "Entities scanned: ") ("Entities scanned: ") (princprinc entcountentcount) () (terpriterpri))((princprinc "Layer1 entities: ") ("Layer1 entities: ") (princprinc layercountlayercount) () (terpriterpri))

))

Page 29: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

(ssget) or VL automation(ssget) or VL automation

((setqsetq ssss ((ssgetssget "x" (list (cons 8 “Layer1”) (cons 410 ("x" (list (cons 8 “Layer1”) (cons 410 (getvargetvar ""ctabctab")))))")))))((princprinc ((strcatstrcat ""\\n" (n" (itoaitoa ((sslengthsslength ssss)) " object(s) found on Layer1“)))) " object(s) found on Layer1“))

((setqsetq app (app (vlaxvlax--getget--acadacad--object))object))((setqsetq doc (doc (vlavla--getget--activedocumentactivedocument app))app))((setqsetq layout (layout (vlavla--getget--activelayoutactivelayout doc))doc))((setqsetq block (block (vlavla--getget--block layout))block layout))((vlaxvlax--forfor entent blockblock

(if (and ((if (and (setqsetq layername2 (layername2 (vlavla--getget--layerlayer entent))))(equal ((equal (strcasestrcase layername2) “LAYER1”) )layername2) “LAYER1”) )

((setqsetq n (+ n 1))n (+ n 1))) )) )

Page 30: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

C++ SampleC++ Sample

Uses native C++ Uses native C++ ObjectARXObjectARX APIAPILayers can be compared by name or by idLayers can be compared by name or by id

acdbOpenObjectacdbOpenObject((pBTRpBTR, , idBtridBtr, , AcDbAcDb::::kForReadkForRead););AcDbBlockTableRecordIteratorAcDbBlockTableRecordIterator **pBTRIterpBTRIter;;pBTRpBTR-->>newIteratornewIterator((pBTRIterpBTRIter););intint nNumFoundnNumFound = 0;= 0;AcDbObjectIdAcDbObjectId entIdentId;;for (; !for (; !pBTRIterpBTRIter-->done(); >done(); pBTRIterpBTRIter-->step()) {>step()) {

pBTRIterpBTRIter-->>getEntityIdgetEntityId((entIdentId););AcDbEntityAcDbEntity **pEntpEnt;;acdbOpenObjectacdbOpenObject((pEntpEnt, , entIdentId, , AcDbAcDb::::kForReadkForRead););if (if (pEntpEnt-->>layerIdlayerId() == idLayer1)() == idLayer1)

nNumFoundnNumFound++;++;pEntpEnt-->close();>close();

}}

Page 31: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

C# SampleC# Sample

Uses automation, is InUses automation, is In--ProcProcLayer compare can be by name or by idLayer compare can be by name or by id

Database db = Application.Database db = Application.DocumentManagerDocumentManager..MdiActiveDocumentMdiActiveDocument.Database;.Database;BlockTableBlockTable btbt = (= (BlockTableBlockTable)tm.)tm.GetObjectGetObject(db.(db.BlockTableIdBlockTableId,,

OpenModeOpenMode..ForReadForRead, false);, false);BlockTableRecordBlockTableRecord btrbtr = = BlockTableRecordBlockTableRecord)tm.)tm.GetObjectGetObject((btbt[[

BlockTableRecordBlockTableRecord..ModelSpaceModelSpace], ], OpenModeOpenMode..ForReadForRead, false);, false);foreachforeach(ObjectId (ObjectId oidoid in in btrbtr) {) {

Object Object objobj = tm.= tm.GetObjectGetObject(oid,OpenMode.ForRead,true);(oid,OpenMode.ForRead,true);Entity entity = (Entity)Entity entity = (Entity)objobj;;String s = entity.Layer;String s = entity.Layer;if (s == "Layer1")if (s == "Layer1")

nNumTimesnNumTimes++;++;

Page 32: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Results from Results from FindLayerFindLayer TestsTests

0.00 (!)0.00 (!)C++ Layer C++ Layer IdxIdx1.151.15Lisp (Lisp (ssgetssget))1.001.00C# C# cmpcmp idsids1.401.40C# C# cmpcmp namesnames0.180.18C++ NativeC++ Native7.507.50VL AutomationVL Automation8.708.70AutoLispAutoLisp2.702.70VBAVBA2.802.80VB ActiveXVB ActiveX

SecsSecsLanguageLanguage

325.05325.05VB6 Out of ProcVB6 Out of Proc

776.09776.09C++ Out of C++ Out of ProcProc

683.01683.01C# Out of ProcC# Out of Proc

Page 33: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Comparing InComparing In--Proc OverheadProc Overhead

2.80

2.70

8.70

1.15

7.50

0.18

1.40

1.00

0.00 2.00 4.00 6.00 8.00 10.00

VB ActivX

VBA

ALisp

Lisp ssget

VL automtn

C++ nativ

C# by nam

C# by id

Lang.

Secs

Page 34: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Memory IssuesMemory Issues

Virtual memory usage is critical in “large” appsVirtual memory usage is critical in “large” appsLarge numbers of objects created and destroyedLarge numbers of objects created and destroyedLarge overall footprint can cause swappingLarge overall footprint can cause swappingLeaks can lead to footprint growthLeaks can lead to footprint growthFragmentation can slow down heap and grow Fragmentation can slow down heap and grow footprintfootprint

Page 35: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Virtual Memory ConceptsVirtual Memory Concepts

Physical RAM is managed by the OSPhysical RAM is managed by the OSVirtual memory is what programs seeVirtual memory is what programs seeWin32 virtual address space is 32Win32 virtual address space is 32--bits = 4G.bits = 4G.2G is normally usable by app, can expand to 3G2G is normally usable by app, can expand to 3GVirtual Memory overflows into swap file(s)Virtual Memory overflows into swap file(s)Memory in win32 is divided into 4K pagesMemory in win32 is divided into 4K pagesOS brings parts of app into phys RAM on OS brings parts of app into phys RAM on demand, and also unloads parts as neededdemand, and also unloads parts as needed

Page 36: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Memory PagesMemory Pages

Types of memory pages: code, data, stack, heapTypes of memory pages: code, data, stack, heapCode and Code and readonlyreadonly data pages are shareddata pages are sharedThe Working Set is the set of pages that the app The Working Set is the set of pages that the app is currently usingis currently using

OS tries to keep working set in physical RAMOS tries to keep working set in physical RAMIn windows, task manager reports working setIn windows, task manager reports working setThrashing occurs when WS doesn’t fit in RAMThrashing occurs when WS doesn’t fit in RAM

Page faults occur when pages are brought inPage faults occur when pages are brought in

Page 37: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Committed Committed vsvs Reserved PagesReserved Pages

Win32’s Win32’s VirtualAllocVirtualAlloc() function can reserve () function can reserve and/or commit memoryand/or commit memoryCommitted pages have swap file backingCommitted pages have swap file backingCode pages have executable file backingCode pages have executable file backingCost of Cost of VirtualAllocVirtualAlloc() occurs when page is () occurs when page is accessedaccessedWindows reserves on 64K boundaries, so there’s Windows reserves on 64K boundaries, so there’s no point in reserving smaller than 64Kno point in reserving smaller than 64K

Page 38: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Task Manager Memory ColumnsTask Manager Memory Columns

Page 39: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

HeapsHeaps

The C Runtime Lib heap is used by defaultThe C Runtime Lib heap is used by defaultThe “The “acadacad heap”: heap”: acdbAllocacdbAlloc, , acdbFreeacdbFree

class class MyClassMyClass : public : public AcHeapOperatorsAcHeapOperators,,public public MyBaseMyBase

Win32 also has Win32 also has HeapAllocHeapAlloc, , HeapFreeHeapFreeCan create dedicated heaps this wayCan create dedicated heaps this wayEntire dedicated heap can be destroyed at onceEntire dedicated heap can be destroyed at once

GlobalAllocGlobalAlloc and and LocalAllocLocalAlloc are Win16 relicsare Win16 relics

Page 40: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Small Block HeapsSmall Block Heaps

Classic heap implementations use lists of blocksClassic heap implementations use lists of blocksTakes an extra 4 bytes (at least) per allocationTakes an extra 4 bytes (at least) per allocationFragmentation can occur after freeingFragmentation can occur after freeing

SBA heaps group blocks of same size togetherSBA heaps group blocks of same size togetherNo size field needed at front of blockNo size field needed at front of blockNo free list, so no fragmentationNo free list, so no fragmentationAcadAcad heap is an SBA heap (up to size 256)heap is an SBA heap (up to size 256)set_set_sbhsbh_threshold() enables _threshold() enables clib’sclib’s SBH modeSBH mode

Page 41: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Heap Timing (standalone)Heap Timing (standalone)

1.4391.4391.2571.257CrtCrt w/o w/o sbhsbh

1.3881.3881.2881.288HeapAllocHeapAlloc

1.4831.4831.3391.339LocalAllocLocalAlloc

0.6800.6801.5031.503CrtCrt w/w/sbhsbh

1.3761.3761.2011.201HeapAllocHeapAlloc

1.4201.4201.1201.120LocalAllocLocalAlloc

0.6740.6741.3791.379CrtCrt w/w/sbhsbh

deallocdeallocallocallocHeapHeapExe doing 4M Exe doing 4M different different allocsallocs and and frees (not in frees (not in acadacad))Block sizes are 4 to Block sizes are 4 to 7676Times shown are Times shown are ticks per ticks per allocalloc or or freefree

Page 42: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Heap Timing (Heap Timing (ArxArx App)App)

1.3371.3371.6601.660HeapAllocHeapAlloc1.5831.5831.7471.747LocalAllocLocalAlloc0.6730.6730.4750.475AcadAcad//acdbacdb0.7490.7491.1481.148ClibClib w/w/sbhsbh1.2271.2271.6581.658HeapAllocHeapAlloc1.3341.3341.5871.587LocalAllocLocalAlloc0.6740.6740.4750.475AcadAcad//acdbacdb0.7480.7481.0801.080ClibClib w/w/sbhsbhFreeFreeAllocAllocHeapHeapArxArx doing 4M different doing 4M different

allocsallocs and frees (not in and frees (not in acadacad))Block sizes are 4 to 76Block sizes are 4 to 76Times shown are ticks Times shown are ticks per per allocalloc or freeor free(Can’t disable (Can’t disable Clib’sClib’s sbhsbhin AutoCAD)in AutoCAD)

Page 43: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Memory LeaksMemory Leaks

Compuware’sCompuware’s DevPartnerDevPartner is good, but doesn’t is good, but doesn’t work with AutoCADwork with AutoCADDebug CRT detects leaks and corruptions, but Debug CRT detects leaks and corruptions, but also doesn’t work with AutoCAD also doesn’t work with AutoCAD Classes can track instances and report leaks from Classes can track instances and report leaks from their their ctorsctors//dtorsdtors or new/delete methodsor new/delete methodsManaged .NET code doesnManaged .NET code doesn’’t have leakst have leaks

Page 44: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

DevPartnerDevPartner .Net Memory Tool.Net Memory Tool

Page 45: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Rebasing and Working Set TuningRebasing and Working Set Tuning

Exe and Exe and DllDll files are given a base files are given a base addraddr by linkerby linkerLoadtimeLoadtime relocation happens if relocation happens if addraddr is occupiedis occupiedTry to pick a base address that doesn’t conflictTry to pick a base address that doesn’t conflict

Working set tuning: tell linker how to order Working set tuning: tell linker how to order functions, using a .functions, using a .wstwst input fileinput file

Requires a profiler that tracks function callsRequires a profiler that tracks function callsNo current tools out there to support itNo current tools out there to support itclcl //GyGy separates functions, link /orderseparates functions, link /order

Page 46: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Accessing DrawingsAccessing Drawings

Objects are brought into memory by opening Objects are brought into memory by opening them. They stay in memory until db is deletedthem. They stay in memory until db is deletedInIn--memory size may be 5 to 20 times memory size may be 5 to 20 times dwgdwg sizesizeThe The closeInputcloseInput() method brings all objects in() method brings all objects inNormal editor Normal editor dwgdwg open does a open does a regenregen, followed , followed by a closeInput. All objects are brought inby a closeInput. All objects are brought in“Heavy” operations are open, save, “Heavy” operations are open, save, regenregen

Page 47: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

DwgDwg Open OptimizationsOpen Optimizations

Partial OpenPartial OpenCan select Can select entsents by extents and/or layerby extents and/or layerUses spatial and layer indices, if presentUses spatial and layer indices, if present

XLoadCtlXLoadCtl sysvarsysvar for for XRefsXRefs1 1 --> demand load the file in place> demand load the file in place2 2 --> demand load a local temp copy of the file> demand load a local temp copy of the file

LAZYLOAD LAZYLOAD sysvarsysvar (undocumented)(undocumented)Skips the Skips the CloseInputCloseInput step. Questionable valuestep. Questionable value

Page 48: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Custom Object TricksCustom Object Tricks

Use partial undo recordingUse partial undo recordingReturn false from Return false from cloneMeForDraggingcloneMeForDragging()()

If it’s a large entity or is slow to cloneIf it’s a large entity or is slow to clone

Don’t bother filing nonDon’t bother filing non--id data to some filersid data to some filerskIdFilerkIdFiler, , kIdXlateFilerkIdXlateFiler, , kPurgeFilerkPurgeFiler

Abbreviate default data in Abbreviate default data in dwgIndwgIn//OutFieldsOutFields()()Only if it’s a large enough winOnly if it’s a large enough win

Page 49: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

ArxArx//DbxDbx API Best PracticesAPI Best Practices

Use Use AcDbObjectIdAcDbObjectId instead of name stringsinstead of name stringsUse demand loading of databasesUse demand loading of databasesDelete databases when you’re done with themDelete databases when you’re done with themOpen objects for read if not modifying themOpen objects for read if not modifying themTry not to do too much in reactor callbacksTry not to do too much in reactor callbacks

In In objectModifiedobjectModified, queue up work for later, queue up work for later

Page 50: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

ArxArx//DbxDbx Best Practices cont’dBest Practices cont’d

Use automation in VBA and Use automation in VBA and AutoLispAutoLispDerive From Derive From AcHeapOperatorsAcHeapOperatorsUse Use AcDbObjectIdAcDbObjectId::::isNullisNull(), (), setNullsetNull() instead of () instead of kNullkNull

if (id == if (id == AcDbObjectIdAcDbObjectId..kNullkNull) // inefficient) // inefficient

Don’t bother with Don’t bother with downgradeOpendowngradeOpen() if you () if you don’t have to (closes and reopens object)don’t have to (closes and reopens object)

Page 51: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

ProfilersProfilers

DevPartnerDevPartner from from CompuwareCompuwareMS MS VisVis Studio 2005 will have profilingStudio 2005 will have profiling

Look up “Team System” in Look up “Team System” in msdnmsdn.com.com

Intel Intel VTuneVTune (low level Pentium info)(low level Pentium info)Good profilers report several things:Good profilers report several things:

Time spent in function, and in function + Time spent in function, and in function + calleescalleesNumber of calls to the functionNumber of calls to the functionCall stacks, showing how function is calledCall stacks, showing how function is called

Page 52: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

DevPartnerDevPartner C++ ProfilerC++ Profiler

Page 53: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

DevPartnerDevPartner .Net Profiler.Net Profiler

Page 54: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers
Page 55: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

Performance CountersPerformance Counters

Use Use PerfmonPerfmon to viewto viewCan access counters programmaticallyCan access counters programmaticallyExposing custom countersExposing custom counters

Page 56: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

C++ TechniquesC++ Techniques

Use Use inlininginlining on small functionson small functionsPass large objects by reference, not by valuePass large objects by reference, not by value

void void foofoo((BigTypeBigType & & refToBigrefToBig););instead ofinstead of

void void foofoo((BigTypeBigType bigValbigVal););

In compound if/while tests, put common and In compound if/while tests, put common and cheaper tests firstcheaper tests first

if (if (fastTestfastTest() && () && oftenFalseoftenFalse() && () && slowTestslowTest())())

Page 57: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

C++ Tips cont’dC++ Tips cont’d

Use MSVC optimization switchesUse MSVC optimization switches//Og Og global optimizationglobal optimization//Oy Oy omit stack framesomit stack frames

Use __Use __stdcallstdcall instead of __instead of __cdeclcdecl calling calling convention (so convention (so calleecallee pops stack)pops stack)

WINAPI macro uses __WINAPI macro uses __stdcallstdcall

Use _Use _allocaalloca() to () to allocalloc buffers on stackbuffers on stackchar *p = _char *p = _allocaalloca((bufsizebufsize); // put ); // put bufbuf on stackon stack

Page 58: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

C++ Tips cont’dC++ Tips cont’d

Avoid unnecessary Avoid unnecessary reinitializationreinitialization in loopsin loopsfor (etc) {for (etc) {for (etc) {for (etc) {

intint daysInMonthsdaysInMonths[] = {31,28,31,30,31,30,31,31,[] = {31,28,31,30,31,30,31,31,30, 31, 30, 31 }; }}30, 31, 30, 31 }; }}

Don’t bother with Don’t bother with registerregister keywordkeywordregister register intint x; // just say x; // just say intint x;x;

Page 59: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

C++ Tips cont’dC++ Tips cont’d

Special case Special case asciiascii (0x20..0x7f) chars in code page (0x20..0x7f) chars in code page dependent string handlingdependent string handling

wchar_t wchar_t cvtToUnicodecvtToUnicode(char (char chch)){ if ({ if (chch >= 0x20 && >= 0x20 && chch <= 0x7f)<= 0x7f)

return return chch; // fast ; // fast asciiascii handlinghandlingelse { // deal with code pageelse { // deal with code page

MultibyteToWideCharMultibyteToWideChar((codepagecodepage, etc), etc)}}}}

Page 60: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

General Coding TechniquesGeneral Coding Techniques

The 80/20 Rule (The 80/20 Rule (VilfredoVilfredo Pareto, 1906)Pareto, 1906)Searching in log(n)Searching in log(n)Sorting in n*log(n)Sorting in n*log(n)Don’t Don’t overdesignoverdesign small data setssmall data setsCaching: know when cache is invalidatedCaching: know when cache is invalidatedParallelism: difficult to achieveParallelism: difficult to achieve

Page 61: High Performance AutoCAD Programming - augi.com · PDF fileAutoLISP. provides E-O-D, safety, funkiness! Sample: “Count Layers

SummarySummary

Design with good practicesDesign with good practicesKnow when to optimizeKnow when to optimizeUse timers and benchmarks to identify Use timers and benchmarks to identify bottlenecks and track improvementsbottlenecks and track improvementsUse tools to find hot spots and leaksUse tools to find hot spots and leaksLet us know about issuesLet us know about issues