I'd have no problem with that commit. How are you benchmarking the speed-up?
Simply by timing loading/quitting with a big file (tutorial-basic now loads in 2.59 sec averaged). But these two [] operators are on top of the profile no matter what you do, called hundreds of millions of times. Here's a profile I got for a lengthy node-editing session:
% cumulative self self total time seconds seconds calls s/call s/call name 13.79 9.54 9.54 644838540 0.00 0.00 NR::Point::operator[](unsigned int) const 12.86 18.45 8.90 140250097 0.00 0.00 NR::Point::Point(NR::Point const&) 10.84 25.95 7.50 295333634 0.00 0.00 NR::Point::operator[](unsigned int) 4.68 29.19 3.24 1828 0.00 0.00 Shape::BeginQuickRaster(float&, int&, float) 4.03 31.98 2.79 66910369 0.00 0.00 NR::operator-(NR::Point const&, NR::Point const&) 3.99 34.74 2.76 3717 0.00 0.01 Shape::DistanceLE(NR::Point, double) 3.90 37.44 2.70 95559872 0.00 0.00 FloatLigne::CmpBord(void const*, void const*) 3.71 40.01 2.56 40584303 0.00 0.00 NR::Point::operator=(NR::Point const&) 3.51 42.44 2.43 6697126 0.00 0.00 FloatLigne::InsertBord(int, float, int) 3.11 44.59 2.15 4114 0.00 0.00 Shape::PtWinding(NR::Point) const 2.12 46.05 1.47 50742 0.00 0.00 FloatLigne::Flatten() 1.94 47.40 1.34 30402734 0.00 0.00 NR::L1(NR::Point const&) 1.57 48.49 1.09 36406933 0.00 0.00 Shape::CmpQRs(void const*, void const*) 1.42 49.47 0.98 50742 0.00 0.00 Shape::QuickScan(float&, int&, float, FloatLigne*, bool, floa 1.40 50.44 0.97 15261101 0.00 0.00 NR::dot(NR::Point const&, NR::Point const&) 1.37 51.39 0.95 13770865 0.00 0.00 NR::operator/(NR::Point const&, double) 1.24 52.25 0.86 112635275 0.00 0.00 NR::Point::Point() 1.20 53.08 0.83 1004 0.00 0.01 Shape::ConvertToShape(Shape*, fill_typ, bool) 1.16 53.88 0.80 2457838 0.00 0.00 Shape::SwapPoints(int, int) 1.13 54.66 0.78 50742 0.00 0.00 IntLigne::Copy(FloatLigne*) 0.92 55.30 0.64 1482 0.00 0.00 Shape::DirectQuickScan(float&, int&, float, bool, float) ....
It might be worth unwrapping the loops in that file, as well.
Tried that, did not help, probably because the compiler unrolls them by itself. I will try inlining and removing checks in more NR:: stuff.
Bryce, you mentioned you have more ideas for optimizing livarot functions that you would try after the 0.39 - I think now is the time :)
Peter, since this is your code, do you have any objections to removing the checks?