• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Delete large number of shapes efficiently

Stats

  • Locked Locked
  • Replies 10
  • Subscribers 144
  • Views 17039
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Delete large number of shapes efficiently

Steve Mikes
Steve Mikes over 11 years ago

I have a large number of shapes that I need to remove from the layout. I find that the delete command seems to take exponenentially increasing amounts of time to run as the number of shapes selected goes up. This creates the perverse situation where it is significantly faster to repeatedly select smaller groups and hit delete than to select them all at once and hit delete. Here's an example:

(note: delete here is the leHiDelete() )

 Select 29,000 objects all at once and hit delete -> ~81 seconds

Manually select a few thousand at a time and delete until all 29,000 are gone  -> 22 seconds

 

That's a huge difference since the 22 seconds includes all the time it takes for me to drag the mouse around in between delete commands. This gets worse the more objects are selected. Is there a more efficient way to do this? I tried writing a recursive delete function that breaks up large lists into smaller ones before deleting, but it doesn't seem to yield any speed improvement:

;; delete alias, speeds up deleting thousands of shapes
procedure( myDelete(@optional objects)
    if(objects == nil
        objects = geGetSelSet()
    );if

    cond(
    (objects == nil leHiDelete())
    (length(objects) < 1000 leHiDelete())
    (t
        info("splitting list of length %d\n" length(objects))
        b = copy(nthcdr(length(objects)/2 objects))
        rplacd(nthcdr(length(objects)/2-1 objects) nil)
        a = copy(objects)
        myDelete(a)
        myDelete(b)
    )
    );cond
)
 

  • Cancel
  • dmay
    dmay over 11 years ago

    Sometimes this is a garbage collection issue. You can try the following:

        needNCells('list        5000000) ; *12 bytes = 60mb
        needNCells('dbobject    2000000) ; *12 bytes = 24mb

    This will pre-allocate some memory for list objects and dbobjects and might reduce the number of garbage collection calls taking place when deleting a large number of objects. To see what types of objects might be getting garbage collected, and to see how much memory is set aside for different types of objects, try typing "gcsummary" into your CIW.

    Derek

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    Although in this case, the code won't be doing anything particularly useful - it does a lot of list manipulation (which calls length multiple times, and copy multiple times, each of which will be creating a fair bit of garbage, as Derek said), but since it doesn't manipulate the selected set, the first leHiDelete() will delete the entire selected set, and the subsequent calls to leHiDelete will be doing nothing. 

    Given that the delete is implemented in C, I suspect that most attempts to make it faster by chunking the deletes into smaller pieces will be offset by the list manipulation that you're doing or by calling dbDeleteObject more often (if you used that instead).

    You didn't mention which version you're using - but either way, if you have a performance issue with the standard delete, you should contact customer support.

    I just deleted a million shapes in IC616 in 20 seconds (running on my Linux laptop) using the delete command (leHiDelete). That doesn't seem unreasonable for something you presumably wouldn't do very often...

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Steve Mikes
    Steve Mikes over 11 years ago

     Andrew,

    I'm running IC6.1.5-64b.500.15

    I'd be just fine with 20 seconds but it's taking 10's of minutes... 

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    Three things I would try in this situation:

     

    1. Use Layout-L mode rather than Layout-XL or Layout-GXL.  

    The connectivity extractor may be wasting your time.

    2. CIW -> Options ->  User Preferences -> Undo Limit = 0  

    The undo list may be wasting your time.

    3.  Don't select anything.  Use dbDeleteObject() rather than leHiDelete().

    This avoids wasting time updating the selected set (and the "previous selected set").

     

    If none of those help, you could try using the profiler to find out where the time is being spent.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Steve Mikes
    Steve Mikes over 11 years ago

     tweeks,

    Your third suggestion seems to be the magic bullet. (I don't have a license for SKILL dev tools so can't access the profiler unfortunately)

    I updated my script to this now:

     ;; delete alias, speeds up deleting thousands of shapes
    procedure( myDelete()
        objects = geGetSelSet()
        cond(
        (objects == nil leHiDelete())
        (t
            geDeselectAllFig()
            foreach(obj objects
                dbDeleteObject(obj)
            );foreach
        )
        );cond
    )

    I had tried almost the same thing before, but I didn't have the geDeselectAllFig() in there. Adding that line makes all the difference.

     Thanks!

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    Thanks for the update, Steve.

    It seems the moral of this story is that updating the selected set is a relatively expensive operation in Virtuoso.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    Although something fishy appears to be happening here, because I don't see this performance issue. Maybe it happens in certain circumstances, and it would be worth exploring that via customer support in case there's something that needs optimizing. If you are deleting the selected set, there is no good reason why it should be faster to do that in SKILL by deselecting first. I would expect there to be some benefit in directly deleting the objects (i.e. what leHiDelete() is doing) because there would be no need to create (and destroy) the SKILL objects for each object being deleted. We could be doing something similar in our code (or should be) if it made that much of a difference in general.

    So please talk to customer support about this.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    Andrew Beckett said:

    If you are deleting the selected set, there is no good reason why it should be faster to do that in SKILL by deselecting first.

     

    I can imagine dbDeleteObject() doing a linear search through the internal list of selected objects so that its argument can be deseleted before deletion. (This assumes the selected set is represented as a list internally.) However, I agree there's no reason leHiDelete() would have to do that: It could just walk down the selection list deslecting and deleting everything that is deletable.

    If the programmers coded leHiDelete() to simply call dbDeleteObject() in a loop, that would explain how Steve gained a significant speed up by deselecting first!

    I would be curious to see how fast this is:

    geDeleteSelSet(hiGetCurrentWindow())
    
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    I've not read through the entire code (it's quite complex to handle all the scenarios that delete needs to handle, including partial selection), but I'd be rather surprised if it was this simplistic as that would be obviously slow with a large number of shapes.

    It's also not going to be hardware related (you seem to have removed that from your post) - since I was seeing 20 seconds for more objects than Steve, and he was talking about 10s of minutes. That's way too big a difference.

    So guessing isn't going to get anywhere - I'd sooner we try to ensure customer support can reproduce the problem then we can properly investigate why it is so slow for Steve. I'm guessing that there is something particular about his data which means that it is more complex than my deletion. For example, if you have large multi-part paths - this is one selected object in the layout editor, but many shapes that have to be actually deleted - and all the ROD info cleaned up too. Even then, it's surprising that dbDeleteObject in a loop is quicker. So we need to see the data to understand what is special and if there really is a problem in the software (which there may be, of course).

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago
    I see.  Thanks Andrew.
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information