0

データが比較的高速 (毎秒 200 回) で受信される場合に、iPhone でカンマ区切りのログ ファイルを作成する方法の提案/実装を探しています。各データ ポイントのタイムスタンプと 2 ~ 3 個の整数をキャプチャすることを期待しています。15 分間で、15*60*200 = 180,000 行のデータがあり、それぞれにタイムスタンプ、いくつかの整数、および改行文字があります。

このデータのディスクへの書き込みが正しい順序で行われるようにしたいと考えています。

私の現在の実装は、1 秒あたり 1 データ ポイントで受信するデータ用に最適化されており、「高速」データにはあまり効率的ではない可能性があります。コードを微調整して、書き込みごとにリソースをあまり消費せずにバックグラウンド スレッドで実行できるようにするにはどうすればよいですか? あるいは、数字を指定して後でログファイルを要求できる高速な「データファイルへのログ」実装はありますか?

   NSString *appDataFile ;
    NSFileHandle *aFileHandle;

-(NSString*)dataFilePath
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    appDataFile = [documentsDirectory stringByAppendingPathComponent:@"Data"];
    aFileHandle = [NSFileHandle fileHandleForWritingAtPath:appDataFile];
    return appDataFile;
}

//creates a new log file for each app run, or appends to existing log
-(void)writeStringToDataFile:(NSString *)csvLine
{

    if(aFileHandle)
    {
        //telling aFilehandle what file write to
        [aFileHandle truncateFileAtOffset:[aFileHandle seekToEndOfFile]]; //setting aFileHandle to write at the end of the file
        [aFileHandle writeData:[csvLine dataUsingEncoding:NSUTF8StringEncoding]];

    }else{
        NSData* headers = [@"timestamp,waveform amplitude,score, connection, event\n" dataUsingEncoding:NSUTF8StringEncoding];

        //clear the old log file
        NSError *error = nil;
        NSFileManager* fileManager =  [NSFileManager defaultManager];
        [fileManager removeItemAtPath:[self dataFilePath] error:&error];

        //create CSV headers
        aFileHandle = [NSFileHandle fileHandleForWritingAtPath:appDataFile];
        [headers writeToFile:appDataFile atomically:YES];

        aFileHandle = [NSFileHandle fileHandleForWritingAtPath:appDataFile];
        //telling aFilehandle what file write to
        [aFileHandle truncateFileAtOffset:[aFileHandle seekToEndOfFile]]; //setting aFileHandle to write at the end of the file
        [aFileHandle writeData:[csvLine dataUsingEncoding:NSUTF8StringEncoding]];

    }

}
4

1 に答える 1

2

明らかな変更の 1 つは、書き込みたい行ごとにファイルを切り捨てるための不要な呼び出しを削除することです。ファイルを開くときに、ハンドルを最後まで 1 回移動するだけです。

次の変更は、Objective-C の代わりに C コードを使用することです。を使用fopenしてファイルを開きます。fputsC 文字列を書き込むために使用します。

チェックするもう 1 つの場所は、csvLine. 使用stringWithFormatは遅いです。低レベルになり、 を使用して C 文字列として各個別の値を書き込みますfputs。フォーマットする必要はありません。NSData に変換する必要はありません。

また、タイムスタンプを行う方法も見てください。を に変換するNSDateNSString、多くの時間が無駄になります。

大きな提案は次のとおりです。時間が非常に重要な場合は、メモリ内に大きな変更可能な文字列を作成し、完了したらすべてを一度にファイルに書き込みます。これにより、タイム クリティカルな段階でファイル I/O が削減されます。

Instruments を使用して、真のボトルネックがどこにあるかを見つけます。これがないと、間違ったコードを最適化する可能性があります。

于 2013-03-10T01:28:15.323 に答える