@@ -800,27 +800,39 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
800800                    // words, and this happens often enough that it's a 
801801                    // performance win. Also, we only need to operate on the 
802802                    // in-use words, hence the slicing. 
803-                     let  op = |a,  b| a | b; 
804803                    let  num_words = num_words ( chunk_domain_size as  usize ) ; 
805-                     if  bitwise_changes ( 
804+ 
805+                     // If both sides are the same, nothing will change. This 
806+                     // case is very common and it's a pretty fast check, so 
807+                     // it's a performance win to do it. 
808+                     if  self_chunk_words[ 0 ..num_words]  == other_chunk_words[ 0 ..num_words]  { 
809+                         continue ; 
810+                     } 
811+ 
812+                     // Do a more precise "will anything change?" test. Also a 
813+                     // performance win. 
814+                     let  op = |a,  b| a | b; 
815+                     if  !bitwise_changes ( 
806816                        & self_chunk_words[ 0 ..num_words] , 
807817                        & other_chunk_words[ 0 ..num_words] , 
808818                        op, 
809819                    )  { 
810-                         let  self_chunk_words = Rc :: make_mut ( self_chunk_words) ; 
811-                         let  has_changed = bitwise ( 
812-                             & mut  self_chunk_words[ 0 ..num_words] , 
813-                             & other_chunk_words[ 0 ..num_words] , 
814-                             op, 
815-                         ) ; 
816-                         debug_assert ! ( has_changed) ; 
817-                         * self_chunk_count =
818-                             count_ones ( & self_chunk_words[ 0 ..num_words] )  as  ChunkSize ; 
819-                         if  * self_chunk_count == chunk_domain_size { 
820-                             * self_chunk = Ones ; 
821-                         } 
822-                         changed = true ; 
820+                         continue ; 
821+                     } 
822+ 
823+                     // If we reach here, `self_chunk_words` is definitely changing. 
824+                     let  self_chunk_words = Rc :: make_mut ( self_chunk_words) ; 
825+                     let  has_changed = bitwise ( 
826+                         & mut  self_chunk_words[ 0 ..num_words] , 
827+                         & other_chunk_words[ 0 ..num_words] , 
828+                         op, 
829+                     ) ; 
830+                     debug_assert ! ( has_changed) ; 
831+                     * self_chunk_count = count_ones ( & self_chunk_words[ 0 ..num_words] )  as  ChunkSize ; 
832+                     if  * self_chunk_count == chunk_domain_size { 
833+                         * self_chunk = Ones ; 
823834                    } 
835+                     changed = true ; 
824836                } 
825837            } 
826838        } 
@@ -874,28 +886,29 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
874886                    Mixed ( self_chunk_count,  self_chunk_words) , 
875887                    Mixed ( _other_chunk_count,  other_chunk_words) , 
876888                )  => { 
877-                     // See [`<Self as BitRelations<ChunkedBitSet<T>>>::union`] for the explanation 
878-                     let  op = |a :  u64 ,  b :  u64 | a &  !b; 
889+                     // See `ChunkedBitSet::union` for details on what is happening here. 
879890                    let  num_words = num_words ( chunk_domain_size as  usize ) ; 
880-                     if  bitwise_changes ( 
891+                     let  op = |a :  u64 ,  b :  u64 | a &  !b; 
892+                     if  !bitwise_changes ( 
881893                        & self_chunk_words[ 0 ..num_words] , 
882894                        & other_chunk_words[ 0 ..num_words] , 
883895                        op, 
884896                    )  { 
885-                         let  self_chunk_words = Rc :: make_mut ( self_chunk_words) ; 
886-                         let  has_changed = bitwise ( 
887-                             & mut  self_chunk_words[ 0 ..num_words] , 
888-                             & other_chunk_words[ 0 ..num_words] , 
889-                             op, 
890-                         ) ; 
891-                         debug_assert ! ( has_changed) ; 
892-                         * self_chunk_count =
893-                             count_ones ( & self_chunk_words[ 0 ..num_words] )  as  ChunkSize ; 
894-                         if  * self_chunk_count == 0  { 
895-                             * self_chunk = Zeros ; 
896-                         } 
897-                         changed = true ; 
897+                         continue ; 
898898                    } 
899+ 
900+                     let  self_chunk_words = Rc :: make_mut ( self_chunk_words) ; 
901+                     let  has_changed = bitwise ( 
902+                         & mut  self_chunk_words[ 0 ..num_words] , 
903+                         & other_chunk_words[ 0 ..num_words] , 
904+                         op, 
905+                     ) ; 
906+                     debug_assert ! ( has_changed) ; 
907+                     * self_chunk_count = count_ones ( & self_chunk_words[ 0 ..num_words] )  as  ChunkSize ; 
908+                     if  * self_chunk_count == 0  { 
909+                         * self_chunk = Zeros ; 
910+                     } 
911+                     changed = true ; 
899912                } 
900913            } 
901914        } 
@@ -931,28 +944,29 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
931944                    Mixed ( self_chunk_count,  self_chunk_words) , 
932945                    Mixed ( _other_chunk_count,  other_chunk_words) , 
933946                )  => { 
934-                     // See [`<Self as BitRelations<ChunkedBitSet<T>>>::union`] for the explanation 
935-                     let  op = |a,  b| a &  b; 
947+                     // See `ChunkedBitSet::union` for details on what is happening here. 
936948                    let  num_words = num_words ( chunk_domain_size as  usize ) ; 
937-                     if  bitwise_changes ( 
949+                     let  op = |a,  b| a &  b; 
950+                     if  !bitwise_changes ( 
938951                        & self_chunk_words[ 0 ..num_words] , 
939952                        & other_chunk_words[ 0 ..num_words] , 
940953                        op, 
941954                    )  { 
942-                         let  self_chunk_words = Rc :: make_mut ( self_chunk_words) ; 
943-                         let  has_changed = bitwise ( 
944-                             & mut  self_chunk_words[ 0 ..num_words] , 
945-                             & other_chunk_words[ 0 ..num_words] , 
946-                             op, 
947-                         ) ; 
948-                         debug_assert ! ( has_changed) ; 
949-                         * self_chunk_count =
950-                             count_ones ( & self_chunk_words[ 0 ..num_words] )  as  ChunkSize ; 
951-                         if  * self_chunk_count == 0  { 
952-                             * self_chunk = Zeros ; 
953-                         } 
954-                         changed = true ; 
955+                         continue ; 
955956                    } 
957+ 
958+                     let  self_chunk_words = Rc :: make_mut ( self_chunk_words) ; 
959+                     let  has_changed = bitwise ( 
960+                         & mut  self_chunk_words[ 0 ..num_words] , 
961+                         & other_chunk_words[ 0 ..num_words] , 
962+                         op, 
963+                     ) ; 
964+                     debug_assert ! ( has_changed) ; 
965+                     * self_chunk_count = count_ones ( & self_chunk_words[ 0 ..num_words] )  as  ChunkSize ; 
966+                     if  * self_chunk_count == 0  { 
967+                         * self_chunk = Zeros ; 
968+                     } 
969+                     changed = true ; 
956970                } 
957971            } 
958972        } 
0 commit comments