c++ - 访问存储在计算机内存中的信息时的查询时间问题

标签 c++

我正在开发一个简单的程序,模拟一个小型数据库。而且我在读取存储在计算机内存中的信息时遇到一个奇怪的问题。问题是查询时间比预期的要长得多,我不明白为什么。让我详细解释一下我的问题,最后,你会发现我的问题是大写的。

首先,我有一个 .txt 文件模拟一个数据库表,其中包含用“|”分隔的随机字符串。这里有一个表格示例(5 行和 5 列)。

Table.txt

0|42sKuG^uM|24465\lHXP|2996fQo\kN|293cvByiV
1|14772cjZ`SN|28704HxDYjzC|6869xXj\nIe|27530EymcTU
2|9041ByZM]I|24371fZKbNk|24085cLKeIW|16945TuuU\Nc
3|16542M[Uz\|13978qMdbyF|6271ait^h|13291_rBZS
4|4032aFqa|13967r^\\`T|27754k]dOTdh|24947]v_uzg

.txt 文件中的此信息由我的程序读取并存储在计算机内存中。这里有从文件中读取此信息并将其存储在计算机中的代码部分。

从 Table.txt 文件中读取数据并将其存储在计算机内存中的代码

string ruta_base("C:\\a\\Table.txt"); // Folder where my "Table.txt" is found

string temp; // Variable where every row from the Table.txt file will be firstly stored
vector<string> buffer; // Variable where every different row will be stored after separating the different elements by tokens.
vector<ElementSet> RowsCols; // Variable with a class that I have created, that simulated a vector and every vector element is a row of my table

ifstream ifs(ruta_base.c_str());

while(getline( ifs, temp )) // We will read and store line per line until the end of the ".txt" file. 
{
    size_t tokenPosition = temp.find("|"); // When we find the simbol "|" we will identify different element. So we separate the string temp into tokens that will be stored in vector<string> buffer

    while (tokenPosition != string::npos)
    {    
        string element;
        tokenPosition = temp.find("|");      

        element = temp.substr(0, tokenPosition);
        buffer.push_back(element);
        temp.erase(0, tokenPosition+1);
    }

    ElementSet ss(0,buffer); 
    buffer.clear();
    RowsCols.push_back(ss); // We store all the elements of every row (stores as vector<string> buffer) in a different position in "RowsCols" 
}

vector<Table> TablesDescriptor;

Table TablesStorage(RowsCols);
TablesDescriptor.push_back(TablesStorage);

DataBase database(1, TablesDescriptor);

之后是重要部分。假设我想进行查询,并要求输入。假设我的查询是行“n”,以及连续的元组“numTuples”和列“y”。 (我们必须说列数由一个十进制数“y”定义,它将被转换为二进制并向我们显示要查询的列,例如,如果我要求第 54 列(二进制为 00110110)我将要求第 2、3、5 和 6 列)。然后我访问计算机内存以获取所需的信息并将其存储在一个 vector shownVector 中。在这里,我向您展示这段代码的一部分。

根据我的输入访问所需信息的代码

int n, numTuples; 
unsigned long long int y;
clock_t t1, t2;

cout<< "Write the ID of the row you want to get more information: " ;
cin>>n; // We get the row to be represented -> "n"

cout<< "Write the number of followed tuples to be queried: " ;
cin>>numTuples; // We get the number of followed tuples to be queried-> "numTuples"

cout<<"Write the ID of the 'columns' you want to get more information: ";
cin>>y; // We get the "columns" to be represented ' "y"

unsigned int r; // Auxiliar variable for the columns path
int t=0; // Auxiliar variable for the tuples path
int idTable;

vector<int> columnsToBeQueried; // Here we will store the columns to be queried get from the bitset<500> binarynumber, after comparing with a mask
vector<string> shownVector; // Vector to store the final information from the query
bitset<500> mask;
mask=0x1;

t1=clock(); // Start of the query time

bitset<500> binaryNumber = Utilities().getDecToBin(y); // We get the columns -> change number from decimal to binary. Max number of columns: 5000

// We see which columns will be queried
for(r=0;r<binaryNumber.size();r++) //
{               
    if(binaryNumber.test(r) & mask.test(r))  // if both of them are bit "1"
    {
        columnsToBeQueried.push_back(r);
    }
    mask=mask<<1;   
}

do
{
    for(int z=0;z<columnsToBeQueried.size();z++)
    {
        int i;
        i=columnsToBeQueried.at(z);

        vector<int> colTab;
        colTab.push_back(1); // Don't really worry about this

        //idTable = colTab.at(i);   // We identify in which table (with the id) is column_i
        // In this simple example we only have one table, so don't worry about this

        Table selectedTable = database.getPointer().at(0); // It simmulates a vector with pointers to different tables that compose the database, but our example database only have one table, so don't worry            ElementSet selectedElementSet;

        ElementSet selectedElementSet;

        selectedElementSet=selectedTable.getRowsCols().at(n);
        shownVector.push_back(selectedElementSet.getElements().at(i)); // We save in the vector shownVector the element "i" of the row "n"

    }   
    n=n+1;
    t++;            

}while(t<numTuples);

t2=clock(); // End of the query time

float diff ((float)t2-(float)t1);
float microseconds = diff / CLOCKS_PER_SEC*1000000;

cout<<"The query time is: "<<microseconds<<" microseconds."<<endl;

所以我的问题是...为什么查询时间会因表大小而如此不同??? (它与具有 100 行和 100 列的表以及具有 10000 行和 1000 列的表无关)。问题是,当我访问已经保存在计算机内存中的信息时,我直接访问我正在寻找的元素而不是所有表格......因此不考虑表格的大小并查询每个查询的时间应该相同....

非常感谢您的帮助!!! :)

类定义

正如你们中的一些人所要求的,我添加了类 Table 和 ElementSet 的定义:

class ElementSet
{
private:
    int id;
    vector<string> elements; 

public:
    ElementSet(); 
    ElementSet(int, vector<string>); 

    int getId();
    void setId(int);

    vector<string> getElements();
    void setElements(vector<string>);

};

class Table
{
private:
    vector<ElementSet> RowsCols; 

public:
    Table(); 
    Table(vector<ElementSet>); 

    vector<ElementSet> getRowsCols();
    void setRowsCols(vector<ElementSet>);
};


class DataBase
{
     private:
        int id;
        vector<Table> pointer; 

     public:
        DataBase(); 
        DataBase(int, vector<Table>); 

    int getId();
    void setId(int);

    vector<Table> getPointer();
    void setPointer(vector<Table>);

    };

class Utilities
{
        public:
        Utilities();
        static bitset<500> getDecToBin(unsigned long long int);
};

最佳答案

请仔细阅读数据库技术,尤其是范式 和“索引”。

恕我直言,您的代码和概念过于复杂。

  1. 简化设计 代码。
  2. 简化代码改进 可读性、健壮性和 正确性

索引表。

您的需求主要关注两个方面:搜索数据和获取数据。在大多数应用程序中,搜索数据会比获取数据消耗更多的时间。因此,主要目标是使搜索尽可能高效。

大多数数据库将数据放在某个地方并创建索引表索引表 是一种数据结构,可以更轻松(更快)地查找数据。 索引表的一个例子是std::map容器。对于给定的,它将返回一个诀窍是让值成为与键相关的数据的链接、句柄或指针。如果您的数据足够小,您可以简化将数据放置入索引表。

组织数据

如果您的应用程序花费大量时间搜索或获取数据,则它可能是面向数据数据驱动。无论哪种情况,数据都很重要,因此请围绕访问数据更改程序设计。

在数据库理论中,有关于范式的讨论。这些是用于简化(减少重复)数据并使获取更容易的技术。

发展规划

我强烈建议您将数据放入一个简单的容器中,例如 std::vector,然后开始使用索引表。实现索引表后,您的程序将运行更好

如果程序性能不佳,请将数据结构从 std::vector 更改为更易于访问的结构。

查看此回复:At what point is it worth using a database?

关于c++ - 访问存储在计算机内存中的信息时的查询时间问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5248383/

相关文章:

c++ - 为什么STL要为Allocator预留接口(interface)?

c++ - 填充张量的示例代码?

c++ - VS2013中生成MOC文件

c++ - constexprs 是否存储在 .rodata 部分

c++ - 释放内存时出错

C++: Address-of dereference 和 dereference of an address-of

c++ - 比较整数 C++

c++ - Automake 用于所有子目录中的共享库

c++ - 安装 cuda 工具包后 glfwCreateWindow() 失败

c++ - 具有不同数量参数的模板函数