Rhino 6 WIP vs 5: 4X slower on 4K display


#1

I have a short Python script that creates a cavity part from Boolean subtraction of 2 slabs. In Rhino 5 on a 4K display at the full screen size this takes less than a second but in the latest Rhino 6 WIP it requires over 4 sec. If the Rhino 6 window is shrunk to about 0.3 in size (both in X and Y), then the timing is similar. On a 4K screen Rhino 5 uses a 1536 x 864 resolution (the 4K display still runs at its native 3840 x 2160 resolution) which means there are 0.4X as many addressable pixels in X and Y compared to Rhino 6. Thus shrinking the Rhino 6 window to 0.3 of its full screen size makes it look more like Rhino 5 in terms of the number of pixels that have to be drawn. So supporting the 4K display appears to be slowing down Rhino 6 by over 4X compared to V5. Below is the Python script used to generate the timing data.

import rhinoscriptsyntax as rs
import Rhino.Geometry
import time
from time import time
P3d = Rhino.Geometry.Point3d
printTimes = True

def round_Rectangle(t, w, l, z, r):
    if printTimes: startime = time()
    C = r*(1 - 1/1.41421356)
    l1 = rs.AddLine(P3d(t+r,t,z),       P3d(t+w-r,t,z))   # Bottom line
    if printTimes: addline1time = time(); print '    AddLine 1 time = {:.3f}'.format(addline1time - startime)
    l2 = rs.AddLine(P3d(t+w,t+r,z),     P3d(t+w,t+l-r,z)) # right line
    if printTimes: addline2time = time(); print '    AddLine 2 time = {:.3f}'.format(addline2time - addline1time)
    l3 = rs.AddLine(P3d(t+w-r,t+l,z),   P3d(t+r,t+l,z))   # Top line
    if printTimes: addline3time = time(); print '    AddLine 3 time = {:.3f}'.format(addline3time - addline2time)
    l4 = rs.AddLine(P3d(t,t+l-r,z),     P3d(t,t+r,z))     # Left line
    if printTimes: addline4time = time(); print '    AddLine 4 time = {:.3f}'.format(addline4time - addline3time)
    if r > 0.:
        a1 = rs.AddArc3Pt(P3d(t,t+r,z),     P3d(t+r,t,z),     P3d(t+C,t+C,z))     # Bottom Left corner arc
        if printTimes: addarc1time = time(); print '    AddArc 1 time = {:.3f}'.format(addarc1time - addline4time)
        a2 = rs.AddArc3Pt(P3d(t+w-r,t,z),   P3d(t+w,t+r,z),   P3d(t+w-C,t+C,z))   # Bottom Right corner arc
        if printTimes: addarc2time = time(); print '    AddArc 2 time = {:.3f}'.format(addarc2time - addarc1time)
        a3 = rs.AddArc3Pt(P3d(t+w,t+l-r,z), P3d(t+w-r,t+l,z), P3d(t+w-C,t+l-C,z)) # Top Right corner arc
        if printTimes: addarc3time = time(); print '    AddArc 3 time = {:.3f}'.format(addarc3time - addarc2time)
        a4 = rs.AddArc3Pt(P3d(t+r,t+l,z),   P3d(t,t+l-r,z),   P3d(t+C,t+l-C,z))   # Top Left corner arc
        if printTimes: addarc4time = time(); print '    AddArc 4 time = {:.3f}'.format(addarc4time - addarc3time)
        # Put the 8 curves in one list: 4 lines and 4 arcs
        curves = [l1,l2,l3,l4,a1,a2,a3,a4]
    else:
        # Put the 4 lines in one list.
        curves = [l1,l2,l3,l4]
     # Join the curves and delete the 8 input pieces 
    crvs = rs.JoinCurves(curves, True, None) ; rs.DeleteObjects(curves)
    if printTimes: joincurvestime = time(); print '    JoinCurves time = {:.3f}'.format(joincurvestime - addarc4time)
    if printTimes: print '  round_Rectangle time = {:.3f}'.format(time() - startime)
    return crvs
    
def rounded_Slab(w, l, h, t, r):
    if printTimes: startime = time()
    crvs = round_Rectangle(t, w, l, t, r) # Arguments: Offset, w, l, z, Corner_Radius
    if printTimes: roundrectangletime = time(); print '    round_Rectangle time = {:.3f}'.format(roundrectangletime - startime)
    srfs = rs.AddPlanarSrf(crvs)
    if printTimes: addplanarsrftime = time(); print '    AddPlanarSrf time = {:.3f}'.format(addplanarsrftime - roundrectangletime)
    curve = rs.AddLine((t,t,t), (t,t,h)) # Create surface and curve for it to follow
    if printTimes: addlinetime = time(); print '    AddLine time = {:.3f}'.format(addlinetime - addplanarsrftime)
    slab = rs.ExtrudeSurface(srfs[0], curve)
    if printTimes: extrudesurfacetime = time(); print '    ExtrudeSurface time = {:.3f}'.format(extrudesurfacetime - addlinetime)
    rs.DeleteObjects(crvs) ; rs.DeleteObject(srfs) ; rs.DeleteObject(curve)
    if printTimes: print 'rounded_Slab time = {:.3f}'.format(time() - startime)
    return slab
    
start_time = time()
w,l,h,ro,ri,t = 100,150,25,2,8,5
rs.ZoomBoundingBox([P3d(0,0,0), P3d(w,0,0), P3d(w,l,0), P3d(0,l,0), P3d(0,0,h), P3d(w,0,0), P3d(w,l,h), P3d(0,l,h)], None, True)
rs.Command('NoEcho _Grid _ApplyTo=_AllViewport _Extents {} _EnterEnd'.format(max(w, l)*1.5))
for view in rs.ViewNames(): rs.ViewDisplayMode(view, 'Shaded')
base = rounded_Slab(w, l, h, 0, ro)
interior = rounded_Slab(w-2*t, l-2*t, h, t, ri) # interior is like base but shrunk by the thickness of the wall t.
bases = rs.BooleanDifference(base, interior)
print 'Total time = {:.3f}'.format(time() - start_time)

#3

In the next post I collected some timing data with the window at the full screen size. The strange thing that stands out is that subsequent calls to the same procedure, like AddLiine, can be 2X slower in Rhino 6 whereas in Rhino 5 the timing remains consistent.

When the screen size is changed, the timing for the cavity generation in Rhino 5 remains essentially constant, within 10%. But in Rhino 6 WIP it varies considerably, changing by over 400%, and picks up the slower-on-subsequent-calls artifact mentioned below at larger window sizes.


#4

I added internal timings to the code and found something interesting; not only is Rhino 6 WIP slower, with the window at the full-screen size, than Rhino 5 for simple operations like AddLine, these operations can be much slower on subsequent calls. In the list of timings below in the Rhino WIP column notice how the second set of 4 calls to AddLine and AddArc are about 2X slower than the first set of 4. For Rhino 5 the times are very consistent.
-----------Rhino 5------------------------------Rhino 6 WIP--------
AddLine 1 time = 0.016--------------AddLine 1 time = 0.047
AddLine 2 time = 0.016--------------AddLine 2 time = 0.047
AddLine 3 time = 0.016--------------AddLine 3 time = 0.063
AddLine 4 time = 0.000--------------AddLine 4 time = 0.062
AddArc 1 time = 0.016---------------AddArc 1 time = 0.078
AddArc 2 time = 0.016---------------AddArc 2 time = 0.063
AddArc 3 time = 0.000---------------AddArc 3 time = 0.062
AddArc 4 time = 0.031---------------AddArc 4 time = 0.047
JoinCurves time = 0.016------------JoinCurves time = 0.063
round_Rectangle time = 0.125----round_Rectangle time = 0.547
round_Rectangle time = 0.125----round_Rectangle time = 0.563
AddPlanarSrf time = 0.094---------AddPlanarSrf time = 0.172
AddLine time = 0.016----------------AddLine time = 0.094
ExtrudeSurface time = 0.094------ExtrudeSurface time = 0.219
rounded_Slab time = 0.375--------rounded_Slab time = 1.438
AddLine 1 time = 0.000-------------AddLine 1 time = 0.141
AddLine 2 time = 0.016-------------AddLine 2 time = 0.125
AddLine 3 time = 0.016-------------AddLine 3 time = 0.156
AddLine 4 time = 0.000-------------AddLine 4 time = 0.141
AddArc 1 time = 0.016--------------AddArc 1 time = 0.141
AddArc 2 time = 0.016--------------AddArc 2 time = 0.141
AddArc 3 time = 0.016--------------AddArc 3 time = 0.125
AddArc 4 time = 0.016--------------AddArc 4 time = 0.141
JoinCurves time = 0.016-----------JoinCurves time = 0.141
round_Rectangle time = 0.109—round_Rectangle time = 1.266
round_Rectangle time = 0.109—round_Rectangle time = 1.266
AddPlanarSrf time = 0.094--------AddPlanarSrf time = 0.250
AddLine time = 0.016---------------AddLine time = 0.172
ExtrudeSurface time = 0.094-----ExtrudeSurface time = 0.234
rounded_Slab time = 0.359-------rounded_Slab time = 2.453
Total time = 0.922-------------------Total time = 4.516


#5

If I zoom out in Rhino 6 to shrink the display of the cavity to 1/5 of the size in Rhino 5 while it is being generated, then the slowdown of the code is only 65% vs 490%.

       if Rhino6:
        # Zoom out so code speeds up in Rhino6 --> Bandaid to partially fix slowness in Rhino6 on 4K display.
        m = 0.19
        rs.ZoomBoundingBox([P3d(0,0,0), P3d(w/m,0,0), P3d(w/m,l/m,0), P3d(0,l/m,0), P3d(0,0,h/m), P3d(w/m,0,0), P3d(w/m,l/m,h/m), P3d(0,l/m,h/m)], None, True)
    else:
        #Zoom using bounding box of cavity to nicely show its generation.
        rs.ZoomBoundingBox([P3d(0,0,0), P3d(w,0,0), P3d(w,l,0), P3d(0,l,0), P3d(0,0,h), P3d(w,0,0), P3d(w,l,h), P3d(0,l,h)], None, True)

At the end I zoom back in on the bounding box for the cavity:

rs.ZoomBoundingBox([P3d(0,0,0), P3d(w,0,0), P3d(w,l,0), P3d(0,l,0), P3d(0,0,h), P3d(w,0,0), P3d(w,l,h), P3d(0,l,h)], None, True)

This is a work around for the slowdown for now.


(Steve Baer) #6

Is the V5 you are testing with the 32 or 64 bit version?


#7

64 bit.


#8

Version 5 SR13 64-bit
(5.13.60913.21340, 9/13/2016)
Commercial
SN: 4-1500-0101-100-0054067-43712


#9

For Rhino 6 WIP it is:

Work In Progress
(6.0.17031.12411, 1/31/2017)
Beta
SN: 4-1600-0106-100-0054067-61716


(Steve Baer) #10

Are you using the registry hack to get V5 to look OK on 4k displays? I’m curious about why you aren’t getting full resolution in V5.


#11

Following the “Toolbars and Text Too Small on High Resolution Monitors” note on the McNeel Wiki Last modified: 2016/09/05 by pascal, the registry change is on my machine: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide] “PreferExternalManifest”=dword:00000001
and the file Rhino.exe.manifest is installed at: C:\Program Files\Rhinoceros 5 (64-bit)\System\