1,StepFile_Read構造函數中for嵌套while循環導致
sout << " ... STEP File Read ... " << endl; c.Show(); #endif // Creation du StepReaderData LesTypes[rec_argNondef] = Interface_ParamVoid ; LesTypes[rec_argSub] = Interface_ParamSub ; LesTypes[rec_argIdent] = Interface_ParamIdent ; LesTypes[rec_argInteger] = Interface_ParamInteger ; LesTypes[rec_argFloat] = Interface_ParamReal ; LesTypes[rec_argEnum] = Interface_ParamEnum ; LesTypes[rec_argBinary] = Interface_ParamBinary ; LesTypes[rec_argText] = Interface_ParamText ; LesTypes[rec_argHexa] = Interface_ParamHexa ; LesTypes[rec_argMisc] = Interface_ParamMisc ; Standard_Integer nbhead, nbrec, nbpar; lir_file_nbr (&nbhead,&nbrec,&nbpar); // renvoi par lex/yacc Handle(StepData_StepReaderData) undirec = new StepData_StepReaderData(nbhead,nbrec,nbpar); // creation tableau de records for ( Standard_Integer nr = 1; nr <= nbrec; nr ++) { int nbarg; char* ident; char* typrec = 0; lir_file_rec (&ident, &typrec, &nbarg); undirec->SetRecord (nr, ident, typrec, nbarg); if (nbarg>0) { int typa; char* val; Interface_ParamType newtype; while(lir_file_arg (&typa, &val) == 1) { newtype = LesTypes[typa] ; undirec->AddStepParam (nr, val, newtype); } } undirec->InitParams(nr); lir_file_finrec(); } lir_file_fin(1); // on a undirec pret pour la suite #ifdef CHRONOMESURE sout << " ... Step File loaded ... " << endl;
1.1 Interface_FileReaderTool::LoadModel中的while導致速度慢
void Interface_FileReaderTool::LoadModel (const Handle(Interface_InterfaceModel)& amodel) // // Methode generale de lecture d un fichier : il est lu via un FileReaderData // qui doit y donner acces de la facon la plus performante possible // chaque interface definit son FileHeader avec ses methodes, appelees ici { // MGE 16/06/98 // Building of Messages //==================================== Handle(Message_Messenger) TF = Messenger(); //==================================== Handle(Interface_Check) ach = new Interface_Check; SetModel(amodel); // .. Demarrage : Lecture du Header .. if (theerrhand) { try { OCC_CATCH_SIGNALS BeginRead(amodel); // selon la norme } catch (Standard_Failure) { // Sendinf of message : Internal error during the header reading Message_Msg Msg11("XSTEP_11"); TF->Send (Msg11, Message_Info); } } else BeginRead(amodel); // selon la norme // .. Lecture des Entites .. amodel->Reservate (thereader->NbEntities()); Standard_Integer num, num0 = thereader->FindNextRecord(0); num = num0; while (num > 0) { Standard_Integer ierr = 0; // erreur sur analyse d une entite Handle(Standard_Transient) anent; try { OCC_CATCH_SIGNALS for (num = num0; num > 0; num = thereader->FindNextRecord(num)) { num0 = num; // Lecture sous protection contre crash // (fait aussi AddEntity mais pas SetReportEntity) anent = LoadedEntity(num); // Lecture non protegee : utile pour travailler avec dbx //// else //// anent = LoadedEntity(num); // .. Fin Lecture .. if (anent.IsNull()) { // Sending of message : Number of ignored Null Entities Message_Msg Msg21("XSTEP_21"); Msg21.Arg(amodel->NbEntities()); TF->Send (Msg21, Message_Info); continue; } // LoadedEntity fait AddEntity MAIS PAS SetReport (en bloc a la fin) } // ---- fin boucle sur entites num0 = 0; // plus rien } // ---- fin du try, le catch suit // En cas d erreur NON PREVUE par l analyse, recuperation par defaut // Attention : la recuperation peut elle-meme planter ... (cf ierr) catch (Standard_Failure const& anException) { // Au passage suivant, on attaquera le record suivant num0 = thereader->FindNextRecord(num); //:g9 abv 28 May 98: tr8_as2_ug.stp - infinite cycle: (0); #ifdef _WIN32 if (anException.IsKind(STANDARD_TYPE(OSD_Exception))) ierr = 2; #else if (anException.IsKind(STANDARD_TYPE(OSD_Signal))) ierr = 2; #endif //:abv 03Apr00: anent is actually a previous one: if (anent.IsNull()) anent = thereader->BoundEntity(num); if (anent.IsNull()) { if (thetrace > 0) { // Sending of message : Number of ignored Null Entities Message_Msg Msg21("XSTEP_21"); Msg21.Arg(amodel->NbEntities()+1); TF->Send (Msg21, Message_Info); continue; } } /*Handle(Interface_Check)*/ ach = new Interface_Check(anent); //: abv 03 Apr 00: trj3_s1-tc-214.stp: generate a message on exception Message_Msg Msg278("XSTEP_278"); Msg278.Arg(amodel->StringLabel(anent)); ach->SendFail (Msg278); if (ierr == 2) { // Sending of message : reading of entity failed Message_Msg Msg22("XSTEP_22"); Msg22.Arg(amodel->StringLabel(anent)); TF->Send (Msg22, Message_Info); return; } if (!ierr) { //char mess[100]; svv #2 ierr = 1; // ce qui serait bien ici serait de recuperer le texte de l erreur pour ach ... if (thetrace > 0) { // Sending of message : recovered entity Message_Msg Msg23("XSTEP_23"); Msg23.Arg(num); TF->Send (Msg23, Message_Info); } // Finalement, on charge une Entite Inconnue thenbreps ++; Handle(Interface_ReportEntity) rep = new Interface_ReportEntity(ach,anent); Handle(Standard_Transient) undef = UnknownEntity(); AnalyseRecord(num,undef,ach); rep->SetContent(undef); if (thereports.IsNull()) thereports = new TColStd_HArray1OfTransient (1,thereader->NbRecords()); thenbreps ++; thereports->SetValue (num,rep); //if(isValid) amodel->AddEntity (anent); // pas fait par LoadedEntity ... } else { if (thetrace > 0) { // Sending of message : reading of entity failed Message_Msg Msg22("XSTEP_22"); Msg22.Arg(amodel->StringLabel(anent)); TF->Send (Msg22, Message_Info); } // On garde <rep> telle quelle : pas d analyse fichier supplementaire, // Mais la phase preliminaire eventuelle est conservee // (en particulier, on garde trace du Type lu du fichier, etc...) } } // ----- fin complete du try/catch } // ----- fin du while // .. Ajout des Reports, silya if (!thereports.IsNull()) { if (thetrace > 0) { // Sending of message : report Message_Msg Msg24("XSTEP_24"); Msg24.Arg(thenbreps); TF->Send (Msg24, Message_Info); } amodel->Reservate (-thenbreps-10); thenbreps = thereports->Upper(); for (Standard_Integer nr = 1; nr <= thenbreps; nr ++) { if (thereports->Value(nr).IsNull()) continue; Handle(Standard_Transient) anent = thereader->BoundEntity (nr); Handle(Interface_ReportEntity) rep = Handle(Interface_ReportEntity)::DownCast(thereports->Value(nr)); amodel->SetReportEntity (-amodel->Number(anent),rep); } } // Conclusion : peut ne rien faire : selon necessite if (theerrhand) { try { OCC_CATCH_SIGNALS EndRead(amodel); // selon la norme } catch (Standard_Failure) { // Sendinf of message : Internal error during the header reading Message_Msg Msg11("XSTEP_11"); TF->Send (Msg11, Message_Info); } } else EndRead(amodel); // selon la norme }
2,IGESFile_Read