@@ -88,25 +88,52 @@ public RoaringBitmap Optimize()
8888 /// <returns>RoaringBitmap</returns>
8989 public static RoaringBitmap Create ( IEnumerable < int > values )
9090 {
91- // Todo: Optimize this (avoid Linq)
92- var groupbyHb = values . Distinct ( ) . OrderBy ( t => t ) . GroupBy ( Utils . HighBits ) . OrderBy ( t => t . Key ) . ToList ( ) ;
91+ var data = values as int [ ] ?? values . ToArray ( ) ;
92+ if ( data . Length == 0 )
93+ {
94+ return new RoaringBitmap ( new RoaringArray ( 0 , new List < ushort > ( ) , new List < Container > ( ) ) ) ;
95+ }
96+
97+ Array . Sort ( data ) ;
98+
99+ // In-place deduplication (two pointers technique)
100+ var uniqueCount = 1 ;
101+ for ( var i = 1 ; i < data . Length ; i ++ )
102+ {
103+ if ( data [ i ] != data [ uniqueCount - 1 ] )
104+ {
105+ data [ uniqueCount ++ ] = data [ i ] ;
106+ }
107+ }
108+
93109 var keys = new List < ushort > ( ) ;
94110 var containers = new List < Container > ( ) ;
95- var size = 0 ;
96- foreach ( var group in groupbyHb )
111+ var index = 0 ;
112+
113+ while ( index < uniqueCount )
97114 {
98- keys . Add ( group . Key ) ;
99- if ( group . Count ( ) > Container . MaxSize )
115+ var hb = Utils . HighBits ( data [ index ] ) ;
116+ var start = index ;
117+ index ++ ;
118+ while ( index < uniqueCount && Utils . HighBits ( data [ index ] ) == hb )
100119 {
101- containers . Add ( BitmapContainer . Create ( group . Select ( Utils . LowBits ) . ToArray ( ) ) ) ;
120+ index ++ ;
102121 }
103- else
122+
123+ var count = index - start ;
124+ var lows = new ushort [ count ] ;
125+ for ( var j = 0 ; j < count ; j ++ )
104126 {
105- containers . Add ( ArrayContainer . Create ( group . Select ( Utils . LowBits ) . ToArray ( ) ) ) ;
127+ lows [ j ] = Utils . LowBits ( data [ start + j ] ) ;
106128 }
107- size ++ ;
129+
130+ keys . Add ( hb ) ;
131+ containers . Add ( count > Container . MaxSize
132+ ? BitmapContainer . Create ( lows )
133+ : ArrayContainer . Create ( lows ) ) ;
108134 }
109- return new RoaringBitmap ( new RoaringArray ( size , keys , containers ) ) ;
135+
136+ return new RoaringBitmap ( new RoaringArray ( keys . Count , keys , containers ) ) ;
110137 }
111138
112139 /// <summary>
0 commit comments