2

私は現在、多くの異なるノードを使用して、多くのデータを解析するXMLパーサーを作成しています(XMLは私が設計したものではなく、コンテンツを制御することはできません...)

とにかく、現在、ダウンロードして読み込むのに許容できないほど長い時間(約13秒)がかかるので、読み取りの効率を上げる方法を探しています。

ハッシュ値を作成する関数を作成したので、プログラムは多くの文字列比較(NSUInteger比較のみ)を行う必要がなくなりましたが、それでも読み込みの複雑さは軽減されません...

だから私は多分私はIMPの配列を作成できると思ったので、それから私は次のようなことをすることができました:

for(int i = 0; i < [hashValues count]; i ++)
{
    if(currHash == [[hashValues objectAtIndex:i] unsignedIntValue])
    {
        [impArray objectAtIndex:i];
    }   
}

またはそのようなもの。

唯一の問題は、実際にIMP関数を呼び出す方法がわからないことです。

IMPが定義するセレクターを実行することを読みました

IMP tImp = [impArray objectAtIndex:i];
tImp(self, @selector(methodName));

しかし、とにかくセレクターの名前を知る必要がある場合、ポイントは何ですか?

誰かが私がやりたいことを手伝ってくれる?または、パーサーの効率を上げるためのさらにいくつかの方法...

これが私のNSXMLParserデリゲートからの抜粋です:didStartElementから

if([elementName isEqualToString:@"playingFilmData"])
{
    appDelegate.arrPlayingFilms = [[NSMutableArray alloc] init];
appDelegate.arrSessionTimes_ByFilm = [[NSMutableArray alloc] init];
appDelegate.arrSessionTimes_ByCinema = [[NSMutableArray alloc] init];
[self releaseData];
return;
}
else if([elementName isEqualToString:@"film_sessions"])
{
    aFilm.arrSessions = [[NSMutableArray alloc] init];
    [self releaseData];
    return;
}
else if([elementName isEqualToString:@"session"])
{
    aSession = [[ATM_SessionObject alloc] init];
    aSession.session_filmID = aFilm.film_id;
    [self releaseData];
    return;
}
else if([elementName isEqualToString:@"sess"])
{
    aFilm.arrSessions = [[NSMutableArray alloc] init];
    [self releaseData];
    return;
}
else if([elementName isEqualToString:@"cin"])
{
    cinID = [attributeDict objectForKey:@"id"];
    [self releaseData];
    return;
}
else if([elementName isEqualToString:@"s"])
{
    aSession = [[ATM_SessionObject alloc] init];
    aSession.session_filmID = aFilm.film_id;
    aSession.session_cinemaID = cinID;
    [self releaseData];
    return;
}
else if([elementName isEqualToString:@"flm"])
{
    aFilm = [[ATM_FilmObject alloc] init];
    aFilm.film_id = [attributeDict objectForKey:@"id"];
    aFilm.film_epNum = 0;

    [self releaseData];
    return;
}

[self releaseData];

didEndElementから

/*
 *0 = nowShowing_lastUpdate
 *1 = s
 *2 = tit
 *3 = des
 *4 = rate
 *5 = dir
 *6 = act
 *7 = rel
 *8 = flm
 */

NSUInteger numHash = [appDelegate murmerHashKey:elementName WithLegth:[elementName length] AndSeed:42];

if(currentElementValue)
{
if(numHash == [[hashValues objectAtIndex:0] unsignedIntValue])
{
    appDelegate.strNowShowingUpdate = currentElementValue;

    self releaseData];
    return;
}
else if(numHash == [[hashValues objectAtIndex:1] unsignedIntValue])
{
    [aFilm.arrSessions addObject:aSession];
    [appDelegate.arrSessionTimes_ByFilm addObject:aSession];

    [aSession release];
    aSession = nil;
}
else if(numHash == [[hashValues objectAtIndex:2] unsignedIntValue])
{
    [aFilm setValue:currentElementValue forKey:@"film_title"];

    [self releaseData];
    return;
}
else if(numHash == [[hashValues objectAtIndex:3] unsignedIntValue])
{
    [aFilm setValue:currentElementValue forKey:@"film_description"];

    [self releaseData];
    return;
}
else if(numHash == [[hashValues objectAtIndex:4] unsignedIntValue])
{
    [aFilm setValue:currentElementValue forKey:@"film_rating"];

    [self releaseData];
    return;
}
else if(numHash == [[hashValues objectAtIndex:5] unsignedIntValue])
{
    [aFilm setValue:currentElementValue forKey:@"film_directors"];

    [self releaseData];
    return;
}
else if(numHash == [[hashValues objectAtIndex:6] unsignedIntValue])
{
    [aFilm setValue:currentElementValue forKey:@"film_actors"];

    [self releaseData];
    return;
}               
}

if(numHash == [[hashValues objectAtIndex:8] unsignedIntValue])
{
[appDelegate.arrPlayingFilms addObject:aFilm];

[aFilm release];
aFilm = nil;

[self releaseData];
return;
}

[self releaseData];

これが、私が間違っていることをさらに明らかにするのに役立つことを願っています。私が言ったように、私はプログラミングのこの分野に不慣れです(そして実際、私は実際には数学者であり、トレーニングによるプログラマーではありません...)ので、私は何をすべきかを学ぶことに非常に熱心です!!

4

2 に答える 2

3

問題全体の概要を説明せずに、マイクロ最適化を行っています。

XML をスキャン (SAX) していますか、それとも DOM 構造をトラバースしていますか? メモリの問題はありますか? SAX 解析 XML で NSAutoreleasePools が配置されていない場合でも、多くのメモリを割り当てることができます。

objc メソッドのディスパッチがパフォーマンスの問題の原因だとは思いません。ボトルネックを特定するには、Shark を使用する必要があります。解析自体は確かに問題ではありません: リンクされた 1,4MB の XML ファイルを実行するのに 0.1 秒かかりますxmllint -format

さらにヘルプが必要な場合は、実行していることをさらに詳しく説明する必要があります。パーサーの種類、作成しているデータまたはオブジェクト、コードなどです。

于 2010-04-30T01:19:18.467 に答える
1

ことわざがあります:

時期尚早の最適化は諸悪の根源です。

要素名を期待値と比較する必要がある場合は、ある時点で文字列ごとの比較を実行する必要があります。最初にハッシュを比較することで、いくつかの明確な不等号のケースを排除できますが、ハッシュの計算にもコストがかかることを忘れないでください。とにかく、Apple は isEqualToString: を実装するときに、これらの最適化についてまだ考えていなかったと思いますか?

Shark を使用して Objective-C アプリケーションのプロファイリングを行ったところ、極端な場合には obj_message_send のオーバーヘッドが 20 ~ 25% になることがわかりました。したがって、仮説として、すべてのメッセージ sendを削除すると、13 秒が 10 秒に短縮される可能性があります。それで十分ですか?疑わしい。

NSXMLParser の内部で何が起こっているかも考えてみてください。実際の XML を解析するために、常に文字列の比較が行われます。それがしなければならないことと比較すると、文字列の比較はおそらくまったく重要ではありません。最適化の取り組みをどこに向けるのが最適かを見つけるために、コードをプロファイリングする必要があります。13 秒のうち 12 秒が、XML のダウンロード元のホストの IP アドレスの解決に費やされていることが判明した場合、コードに対して何を行っても役に立ちません。

于 2010-04-30T08:42:19.523 に答える