Чтение в 5000 строк текстового файла на Iphone - PullRequest
0 голосов
/ 31 мая 2010

Gday, я пытаюсь создать мозаичную карту для своей игры, у меня раньше это работало с использованием других XML-методов, но у меня были утечки памяти и всевозможные ошибки. Однако время загрузки карты составило 2,5 - 3 секунды.

Итак, я переписал весь код, используя NSMutableStrings и NSStrings. После моей лучшей попытки его оптомить время загрузки карты составило 10 - 11 секунд, что слишком медленно.

Итак, теперь я переписал код, используя массивы char *, только теперь у меня есть время загрузки 18 секунд -_-.

Вот последний код, я немного знаю c, так что я мог бы легко все испортить.

  FILE* file = fopen(a, "r");
  fseek(file, 0L, SEEK_END);
  length = ftell(file);
  fseek(file,0L, SEEK_SET);
  char fileText[length +1];

  char buffer[1024];// = malloc(1024);
  while(fgets(buffer, 1024, file) != NULL)
  {
        strncat(fileText, buffer, strlen(buffer));
  }
  fclose(file);
  [self parseMapFile:fileText];




- (void)parseMapFile:(char*)tiledXML
{


      currentLayerID = 0;
      currentTileSetID = 0;
      tileX = 0;
      tileY = 0;

      int tmpGid;
      NSString* tmpName;
      int tmpTileWidth;
      int tmpTileHeight;
      int tilesetCounter = 0;

      NSString* tmpLayerName;
      int tmpLayerHeight;
      int tmpLayerWidth;
      int layerCounter = 0;
      tileX = 0;
      tileY = 0;
      int tmpFirstGid = 0;


      int x;
      int index;
      char* r;
      int counter = 0;
      while ((x = [self findSubstring:tiledXML substring:"\n"]) != 0)
      {
            counter ++;
            char result[x + 1];
            r = &result[0];
            [self substringIndex:tiledXML index:x newArray:result];
            tiledXML += x+2;
            index = 0;

            if (counter == 1)
            {
                  continue;
            }
            else if (counter == 2)
            {
                  char result1[5];
                  index = [self getStringBetweenStrings:r substring1:"th=\"" substring2:"\"" newArray:result1];
                  if (r != 0);
                        mapWidth = atoi(result1);

                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"ht=\"" substring2:"\"" newArray:result1];
                  if (r != 0);
                        mapHeight = atoi(result1);

                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"th=\"" substring2:"\"" newArray:result1];
                  if (r != 0);
                        tileWidth = atoi(result1);

                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"ht=\"" substring2:"\"" newArray:result1];
                  if (r != 0);
                        tileHeight = atoi(result1);

                  continue;

            }

            char result2[50];
            char result3[3];

            if ((index = [self getStringBetweenStrings:r substring1:" gid=\"" substring2:"\"" newArray:result3]) != 0)
            {

                  tmpGid = atoi(result3);

                  if(tmpGid == 0)
                  {
                        [currentLayer addTileAtX:tileX y:tileY tileSetID:-1 tileID:0 globalID:0];
                  } 
                  else
                  {
                        [currentLayer addTileAtX:tileX 
                              y:tileY 
                              tileSetID:[currentTileSet tileSetID] 
                              tileID:tmpGid - [currentTileSet firstGID] 
                              globalID:tmpGid];
                 }               
                  tileX ++;

                  if (tileX > [currentLayer layerWidth]-1)
                  {
                        tileY ++;
                        tileX = 0;
                  }



            }
            else if ((index = [self getStringBetweenStrings:r substring1:"tgid=\"" substring2:"\"" newArray:result2]) != 0)
            {

                  tmpFirstGid = atoi(result2);

                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"me=\"" substring2:"\"" newArray:result2];
                  if (r != 0);
                        tmpName = [NSString stringWithUTF8String:result2];


                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"th=\"" substring2:"\"" newArray:result2];
                  if (r != 0);
                   tmpTileWidth = atoi(result2);


                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"ht=\"" substring2:"\"" newArray:result2];
                  if (r != 0);
                        tmpTileHeight = atoi(result2);

            }
            else if ((index = [self getStringBetweenStrings:r substring1:"rce=\"" substring2:"\"" newArray:result2]) != 0)
            {


                   currentTileSet = [[TileSet alloc] initWithImageNamed:[NSString stringWithUTF8String:result2] name:tmpName tileSetID:tilesetCounter firstGID:tmpFirstGid tileWidth:tmpTileWidth tileHeight:tmpTileHeight spacing:0];
                   [tileSets addObject:currentTileSet];
                   [currentTileSet release];
                   tilesetCounter ++;


            }
            else if ((index = [self getStringBetweenStrings:r substring1:"r name=\"" substring2:"\"" newArray:result2]) != 0)
            {

                  tileX = 0;
                  tileY = 0;

                  tmpLayerName = [NSString stringWithUTF8String:result2];

                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"th=\"" substring2:"\"" newArray:result2];
                  if (r != 0);
                        tmpLayerWidth = atoi(result2);


                  r += index +1;
                  index = 0;
                  index = [self getStringBetweenStrings:r substring1:"ht=\"" substring2:"\"" newArray:result2];
                  if (r != 0);
                        tmpLayerHeight = atoi(result2);

                  currentLayer = [[Layer alloc] initWithName:tmpLayerName layerID:layerCounter layerWidth:tmpLayerWidth layerHeight:tmpLayerHeight];
                  [layers addObject:currentLayer];
                  [currentLayer release];
                  layerCounter ++;

            }


      }







}




-(void)substringIndex:(char*)c index:(int)x newArray:(char*)result
{
      result[0] = 0;
      for (int i = 0; i < strlen(c); i++)
      {
            result[i] = c[i];
            if (i == x)
            {
                  result[i+1] = '\0';
                  break;

            }

      } 
}


-(int)findSubstring:(char*)c substring:(char*)s
{
      int sCounter = 0;
      int index = 0;

      int d;
      for (int i = 0; i < strlen(c); i ++)
      {
            if (i > 500)//max line size
                  break;
            if (c[i] == s[sCounter])
            {
                  d = strlen(s);
                  sCounter ++;

                  if (d > sCounter)
                  {

                  }
                  else
                  {
                        index = i - (d);
                        break;
                  }
            }
            else
                  sCounter = 0;

       }
                return index;


 }

-(int)getStringBetweenStrings:(char*)c substring1:(char*)s substring2:(char*)s2 newArray:(char*)result
{
      int sCounter = 0;
      int sCounter2 = 0;
      int index = 0;
      int index2 = 0;

      int d;
      for (int i = 0; i < strlen(c); i ++)
      {

            if (index != 0)
            {
                  if (c[i] == s2[sCounter2])
                  {
                        d = strlen(s2);
                        sCounter2 ++;

                        if (d > sCounter2)
                        {

                        }
                        else
                        {
                              index2 = i - (d);
                              break;
                        }
                  }
                  else
                       sCounter2 = 0;


             }
             else
             {
                   if (c[i] == s[sCounter])
                   {
                        d = strlen(s);
                        sCounter ++;

                        if (d > sCounter)
                        {

                        }
                        else
                        {
                              index = i;

                        }
                  }
                  else
                        sCounter = 0;

            }

      }
      if (index != 0 && index2 != 0)
            [self substringIndex:(c + index+1) index:index2-index-1 newArray:result];

 return index;
}

(я знаю, что здесь много кода для вставки) Я подумал, что с помощью базовых массивов символов я мог бы значительно повысить производительность, по крайней мере, по сравнению с исходным кодом на основе узлов, который я заменял.

Спасибо за все ваши усилия.

Ответы [ 2 ]

1 голос
/ 03 июня 2010

Я бы настоятельно рекомендовал вернуться и использовать NSXMLParser, или если вам нужно накатить использование libxml или что-то подобное. Анализаторы XML нетривиальны и очень решаемы. Если у вас есть утечки памяти, в Xcode есть много инструментов, которые помогут вам отследить это.

Другие ваши альтернативы используют списки свойств, которые могут быть сериализованы в двоичном формате, или CoreData.

1 голос
/ 03 июня 2010

Похоже, вы сканируете весь массив каждый раз, когда ищете новую строку, а не начинаете с того места, где остановились?

Попробуйте использовать strtok, который сделает это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...