2012-08-15 105 views
0

我有一個超過280.000+的單詞列表,從SQLite數據庫加載到NSArray。然後我進行快速枚舉以檢查用戶輸入的某個字符串值是否與數組中的某個單詞相匹配。由於數組非常大,因此iphone 4需要大約1-2秒才能通過該陣列。提高快速枚舉性能

我該如何提高性能?也許我應該製作幾個更小的陣列?一個用於字母表中的每個字母,以便有更少的數據要通過。

這是我的數據庫類的外觀

static WordDatabase *_database; 

+(WordDatabase *) database 
{ 

    if (_database == nil) { 

     _database = [[WordDatabase alloc] init]; 

    } 

    return _database; 
} 

- (id) init 
{ 
    if ((self = [super init])) { 
     NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:@"dictionary" ofType:@"sqlite"]; 


     if (sqlite3_open([sqLiteDb UTF8String], &_database) != SQLITE_OK) { 
      NSLog(@"Failed to open database!"); 
     } 
    } 
    return self; 

} 

- (NSArray *)dictionaryWords { 

    NSMutableArray *retval = [[[NSMutableArray alloc] init] autorelease]; 
    NSString *query = @"SELECT word FROM words"; 
    sqlite3_stmt *statement; 

    if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) { 
     while (sqlite3_step(statement) == SQLITE_ROW) { 

      char *wordChars = (char *) sqlite3_column_text(statement, 0); 

      NSString *name = [[NSString alloc] initWithUTF8String:wordChars]; 

      name = [name uppercaseString]; 

      [retval addObject:name]; 

     } 
     sqlite3_finalize(statement); 
    } 

    return retval; 

} 

然後在我的主要觀點我初始化它像這樣

dictionary = [[NSArray alloc] initWithArray:[WordDatabase database].dictionaryWords]; 

,最後我用這個方法

- (void) checkWord 
{  
    NSString *userWord = formedWord.wordLabel.string; 
    NSLog(@"checking dictionary for %@", userWord); 

    for (NSString *word in dictionary) { 
     if ([userWord isEqualToString: word]) { 
     NSLog(@"match found");  
     }  
    } 
} 
經過陣列
+1

所有鍵值對與NSSet中替換的NSArray,然後校驗碼變成[集containsObject:字]。確實是 – 2012-08-15 18:29:08

+0

。將NSArray更改爲NSSet幾乎可以立即進行檢查。儘管字典的初始加載時間稍長一些。但這是一個小的折衷。 – 2012-08-15 19:09:58

+0

雖然這仍然是很多內存。如果你的應用需要做其他的事情,你可能會發現SQL搜索已經足夠好了,特別是當你將數據庫編入索引時......你甚至可以將SQL數據庫作爲一個大表使用。用該單詞創建一個散列,然後向數據庫詢問與該散列匹配的所有單詞。在這個小列表上的線性搜索將不會是什麼,並且對索引整數值的SQL搜索非常快。然後你不必使用所有的內存。 – 2012-08-15 19:23:05

回答

4

許多不同的方式。

  • 堅持所有的單詞在字典或一組,測試存在快速

  • 打破它,你的建議;創建某種樹型結構。

  • 使用數據庫進行搜索。如果構建正確,它們一般都非常好。

+2

你會想要一個集合,而不是一本字典,因爲數據似乎沒有被鍵入。 – 2012-08-15 18:06:01

+0

足夠了;一套將更有效率。 – bbum 2012-08-15 19:34:07

0

如果空間不是問題,請存儲每個單詞的散列值並將其用於基本查找。一旦被哈希過濾,然後比較每個單詞。這將減少昂貴的字符串比較的次數。更容易索引/排序並執行快速查找。

0

我第二個字典。目標c的NSDictionary。

例如:

//要打印出的NSDictionary myDict

for(id key in myDict) 
    NSLog(@"key=%@ value=%@", key, [myDict objectForKey:key]); 
+0

請注意,基於塊的字典枚舉顯着更快,因爲它不需要使用散列查找來獲取值。 – bbum 2012-08-15 19:34:41