seqvec_bench.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: seqvec_bench.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:42:08  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: seqvec_bench.cpp,v 1000.1 2004/06/01 19:42:08 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *    Performance tests for various iterators
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistd.hpp>
  41. #include <corelib/ncbiapp.hpp>
  42. #include <corelib/ncbienv.hpp>
  43. #include <corelib/ncbiargs.hpp>
  44. #include <corelib/ncbitime.hpp>
  45. #include <connect/ncbi_core_cxx.hpp>
  46. // Object Manager includes
  47. #include <objmgr/bioseq_handle.hpp>
  48. #include <objmgr/seq_vector.hpp>
  49. #include <objmgr/scope.hpp>
  50. #include <objmgr/object_manager.hpp>
  51. #include <objtools/data_loaders/genbank/gbloader.hpp>
  52. #include <serial/serial.hpp>
  53. #include <serial/objistrasn.hpp>
  54. #include <util/md5.hpp>
  55. #include <vector>
  56. using namespace ncbi;
  57. using namespace objects;
  58. /////////////////////////////////////////////////////////////////////////////
  59. //
  60. //  Demo application
  61. //
  62. class CSeqVecBench : public CNcbiApplication
  63. {
  64. public:
  65.     virtual void Init(void);
  66.     virtual int  Run (void);
  67.     void start(const char* name);
  68.     void start_iter(void);
  69.     void end_iter(void);
  70.     void end(void);
  71.     void end_all(void);
  72.     CStopWatch sw;
  73.     vector<string> names;
  74.     vector<double> times;
  75.     bool get_best;
  76.     unsigned test_count;
  77.     unsigned counter;
  78.     static int result_mask;
  79. };
  80. void CSeqVecBench::Init(void)
  81. {
  82.     // Prepare command line descriptions
  83.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  84.     // GI to fetch
  85.     arg_desc->AddOptionalKey("id", "Accession",
  86.                              "sequence id to load and test",
  87.                              CArgDescriptions::eString);
  88.     arg_desc->AddDefaultKey("iters", "Iterations",
  89.                              "number of iterations to run",
  90.                              CArgDescriptions::eInteger, "5");
  91.     arg_desc->AddFlag("average", "collect average time instead of minumum");
  92.     arg_desc->AddFlag("iupac", "test Iupac coding");
  93.     arg_desc->AddFlag("minus", "test minus strand of sequence");
  94.     // Pass argument descriptions to the application
  95.     //
  96.     SetupArgDescriptions(arg_desc.release());
  97. }
  98. void CSeqVecBench::start(const char* n)
  99. {
  100.     names.push_back(n);
  101.     times.push_back(0);
  102.     cout << "Running test: " << names.back() << "..." << endl;
  103.     test_count = 0;
  104. }
  105. inline
  106. void CSeqVecBench::start_iter(void)
  107. {
  108.     counter = 0;
  109.     sw.Start();
  110. }
  111. inline
  112. void CSeqVecBench::end_iter(void)
  113. {
  114.     double time = sw.Elapsed();
  115.     if ( get_best ) {
  116.         if ( test_count == 0 || time < times.back() ) {
  117.             times.back() = time;
  118.             test_count = 1;
  119.         }
  120.     }
  121.     else {
  122.         times.back() += time;
  123.         test_count += 1;
  124.     }
  125. }
  126. void CSeqVecBench::end(void)
  127. {
  128.     times.back() /= test_count;
  129.     cout << setw(40) << names.back() << " : " << 
  130.         counter << " bases in " << times.back() << " secs" << endl;
  131. }
  132. void CSeqVecBench::end_all(void)
  133. {
  134.     cout << endl << "Normalized to "<<names.front()<<":" << endl;
  135.     for ( size_t i = 1; i < names.size(); ++i ) {
  136.         cout << setw(40) << names[i] << " : " << (times[i] / times[0]) << endl;
  137.     }
  138. }
  139. int CSeqVecBench::result_mask = 0;
  140. int CSeqVecBench::Run(void)
  141. {
  142.     CArgs args = GetArgs();
  143.     CSeq_id id(args["id"].AsString());
  144.     if (id.Which() == CSeq_id::e_not_set) {
  145.         LOG_POST(Fatal << "seq id " << args["id"].AsString()
  146.                  << " not recognized");
  147.     }
  148.     // Setup application registry, error log, and MT-lock for CONNECT library
  149.     CONNECT_Init(&GetConfig());
  150.     CRef<CObjectManager> object_manager(new CObjectManager());
  151.     object_manager->RegisterDataLoader(*new CGBDataLoader(),
  152.                                        CObjectManager::eDefault);
  153.     CScope scope(*object_manager);
  154.     scope.AddDefaults();
  155.     CBioseq_Handle handle = scope.GetBioseqHandle(id);
  156.     if ( !handle ) {
  157.         LOG_POST(Fatal << "failed to retrieve sequence "
  158.                  << args["id"].AsString());
  159.     }
  160.     // number of iterations we perform
  161.     int iters = args["iters"].AsInteger();
  162.     CBioseq_Handle::EVectorCoding coding = args["iupac"]?
  163.         CBioseq_Handle::eCoding_Iupac: CBioseq_Handle::eCoding_Ncbi;
  164.     CBioseq_Handle::EVectorStrand strand = args["minus"]?
  165.         CBioseq_Handle::eStrand_Minus: CBioseq_Handle::eStrand_Plus;
  166.     get_best = !args["average"];
  167.     //
  168.     // we ignore the first iteration, as additional fetching may occur here
  169.     //
  170.     {{
  171.         cout << "forcing retrieval of whole sequence..." << endl;
  172.         sw.Start();
  173.         string sequence;
  174.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  175.         vec.GetSeqData(0, vec.size(), sequence);
  176.         cout << "  sequence is " << sequence.length() << " bases" << endl;
  177.         CMD5 sum;
  178.         sum.Update(sequence.data(), sequence.size());
  179.         cout << "  md5 sum is: " << sum.GetHexSum() << endl;
  180.         double load_time = sw.Elapsed();
  181.         cout << "  loaded in " << load_time << " seconds" << endl;
  182.     }}
  183.     unsigned char mask = 0;
  184.     int i;
  185.     //
  186.     // test 4: bulk retrieval
  187.     //
  188.     start("only string::const_iterator");
  189.     {{
  190.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  191.         string str;
  192.         vec.GetSeqData(0, vec.size(), str);
  193.         const int mul1 = 1;
  194.         const int mul2 = 3;
  195.         for (i = iters*mul1;  i;  --i) {
  196.             start_iter();
  197.             for ( int j = 0; j < mul2; ++j ) {
  198.                 ITERATE(string, iter, str) {
  199.                     mask ^= *iter;
  200.                     ++counter;
  201.                 }
  202.             }
  203.             end_iter();
  204.         }
  205.         counter /= mul2;
  206.         times.back() /= mul2;
  207.     }}
  208.     end();
  209.     //
  210.     // test 1: iterate CSeqVector using operator[]
  211.     //
  212.     start("CSeqVector::operator[]");
  213.     for (i = 0;  i < iters;  ++i) {
  214.         start_iter();
  215.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  216.         for (size_t j = 0;  j < vec.size();  ++j, ++counter) {
  217.             mask ^= vec[j];
  218.         }
  219.         end_iter();
  220.     }
  221.     end();
  222.     //
  223.     // test 1a: iterate CSeqVector using operator[]
  224.     //
  225.     start("double CSeqVector::operator[]");
  226.     for (i = 0;  i < iters;  ++i) {
  227.         start_iter();
  228.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  229.         for (size_t j = 0;  j < vec.size();  ++j, ++counter) {
  230.             mask ^= vec[j];
  231.             mask ^= vec[j];
  232.         }
  233.         end_iter();
  234.     }
  235.     end();
  236.     //
  237.     // test 2: bulk retrieval
  238.     //
  239.     start("GetSeqData() + string::operator[]");
  240.     for (i = 0;  i < iters;  ++i) {
  241.         start_iter();
  242.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  243.         string str;
  244.         vec.GetSeqData(0, vec.size(), str);
  245.         for (size_t j = 0;  j < str.size();  ++j, ++counter) {
  246.             mask ^= str[j];
  247.         }
  248.         end_iter();
  249.     }
  250.     end();
  251.     //
  252.     // test 3: bulk retrieval
  253.     //
  254.     start("GetSeqData() + string::const_iterator");
  255.     for (i = 0;  i < iters;  ++i) {
  256.         start_iter();
  257.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  258.         string str;
  259.         vec.GetSeqData(0, vec.size(), str);
  260.         ITERATE(string, iter, str) {
  261.             mask ^= *iter;
  262.             ++counter;
  263.         }
  264.         end_iter();
  265.     }
  266.     end();
  267.     //
  268.     // test 4: bulk retrieval
  269.     //
  270.     start("only string::const_iterator");
  271.     {{
  272.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  273.         string str;
  274.         vec.GetSeqData(0, vec.size(), str);
  275.         const int mul1 = 1;
  276.         const int mul2 = 3;
  277.         for (i = iters*mul1;  i;  --i) {
  278.             start_iter();
  279.             for ( int j = 0; j < mul2; ++j ) {
  280.                 ITERATE(string, iter, str) {
  281.                     mask ^= *iter;
  282.                     ++counter;
  283.                 }
  284.             }
  285.             end_iter();
  286.         }
  287.         counter /= mul2;
  288.         times.back() /= mul2;
  289.     }}
  290.     end();
  291.     //
  292.     // test 5: CSeqVector_CI
  293.     //
  294.     start("CSeqVector_CI");
  295.     for (i = 0;  i < iters;  ++i) {
  296.         start_iter();
  297.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  298.         for ( CSeqVector_CI iter(vec); iter; ++iter, ++counter ) {
  299.             mask ^= *iter;
  300.         }
  301.         end_iter();
  302.     }
  303.     end();
  304.     //
  305.     // test 6: ITERATE
  306.     //
  307.     start("ITERATE");
  308.     for (i = 0;  i < iters;  ++i) {
  309.         start_iter();
  310.         CSeqVector vec = handle.GetSeqVector(coding, strand);
  311.         ITERATE ( CSeqVector, iter, vec ) {
  312.             mask ^= *iter;
  313.             ++counter;
  314.         }
  315.         end_iter();
  316.     }
  317.     end();
  318.     end_all();
  319.     result_mask ^= mask;
  320.     
  321.     return 0;
  322. }
  323. /////////////////////////////////////////////////////////////////////////////
  324. //  MAIN
  325. int main(int argc, const char* argv[])
  326. {
  327.     return CSeqVecBench().AppMain(argc, argv, 0, eDS_Default, 0);
  328. }
  329. /*
  330.  * ===========================================================================
  331.  * $Log: seqvec_bench.cpp,v $
  332.  * Revision 1000.1  2004/06/01 19:42:08  gouriano
  333.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  334.  *
  335.  * Revision 1.2  2004/05/21 21:42:52  gorelenk
  336.  * Added PCH ncbi_pch.hpp
  337.  *
  338.  * Revision 1.1  2003/12/16 17:51:16  kuznets
  339.  * Code reorganization
  340.  *
  341.  * Revision 1.2  2003/10/22 17:57:45  vasilche
  342.  * Some code cleaning.
  343.  * Added '-average' option.
  344.  *
  345.  * Revision 1.1  2003/08/29 13:34:48  vasilche
  346.  * Rewrote CSeqVector/CSeqVector_CI code to allow better inlining.
  347.  * CSeqVector::operator[] made significantly faster.
  348.  * Added possibility to have platform dependent byte unpacking functions.
  349.  *
  350.  * Revision 1.1  2003/08/09 13:13:06  dicuccio
  351.  * Initial revision
  352.  *
  353.  * ===========================================================================
  354.  */