Projects/Utils/kwallet/Benchmark

    From KDE TechBase
    < Projects‎ | Utils‎ | kwallet
    Revision as of 19:38, 29 June 2011 by Neverendingo (talk | contribs) (Text replace - "<code cpp>" to "<syntaxhighlight lang="cpp">")


    Projects/Utils/kwallet/Benchmark

    Summary

    One of the main concerns users had with the wallet was that new entries weren't saved immediately (bug #105752). Before actually getting to work and coding a workaround (appending new passwords to the file without reencrypting all of it or creating a second file where new passwords are appended) I benchmarked the existing encryption to check the actual overhead that would be incurred by saving to the kwl file as soon as passwords were entered.

    Code

    I used the following code for benchmarking. Please keep in mind:

    • keys and passwords generated using random data are probably longer than the entries you actually have in your wallet.
    • only syncing the wallet is benchmarked
    • due to hd caching (and a rather modest filesize), most of the time reported should be used encrypting the data.

    <syntaxhighlight lang="cpp">

    1. include <kaboutdata.h>
    2. include <kcomponentdata.h>
    3. include <kcmdlineargs.h>
    4. include <kdebug.h>
    5. include <kwallet.h>
    6. include <QApplication>
    7. include <QTime>
    8. include <QFile>
    1. include "../backend/kwalletentry.h"
    2. include "../backend/kwalletbackend.h"

    using namespace KWallet;

    static int getRandomBlock(QByteArray& randBlock) {

     QFile devrand("/dev/urandom");
     if (devrand.open(QIODevice::ReadOnly)) {
       int rc = devrand.read(randBlock.data(), randBlock.size());
       if (rc != randBlock.size()) {
         return -3;              // not enough data read
       }
       return 0;
     }
    
     return -1;
    

    }


    int main(int argc, char **argv) {

     KAboutData aboutData("kwalletbench", 0, ki18n("kwalletbench"), "version");
     KComponentData componentData(&aboutData);
     QApplication app( argc, argv );
    
     Backend back("/tmp/benchmark.kwl", true);
    
     back.open("benchmark");
     back.createFolder("benchmark");
     back.setFolder("benchmark");
    
     for (int i = 0; i <= 100000; i+=100) {
       for (int j = 0; j < 100; ++j) {
         Entry entry;
         QByteArray key, value;
         key.resize(20);
         if (getRandomBlock(key) != 0) {
           kDebug(0) << "Error";
         }
         value.resize(50);
         if (getRandomBlock(value) != 0) {
           kDebug(0) << "Error";
         }
         entry.setType(Wallet::Password);
         entry.setKey(key);
         entry.setValue(value);
         back.writeEntry(&entry);
       }
    
       QTime _start = QTime::currentTime();
       back.sync("benchmark");
       QTime _end = QTime::currentTime();
    
       kDebug(0) << i << ";" << _start.msecsTo(_end);
     }
    
     back.close();
    
     return 0;
    

    }

    Results

    I benchmarked on a Q6600. As the encrypting code is single-threaded, only one core (2.4GHz) is being used. Please bear in mind that I didn't bother to run the test several times as the results are pretty clear - unfortunately this makes some of the numbers seem a little weird.

    • DebugFull
      • 1 password: 16ms
      • 100 passwords: 15ms
      • 1000 passwords: 32ms
      • 5000 passwords: 107ms
      • 10000 passwords: 192ms
    • Release
      • 1 password: 8ms
      • 100 passwords: 5ms
      • 1000 passwords: 15ms
      • 5000 passwords: 25ms
      • 10000 passwords: 56ms

    Discussion

    I assume that your usual wallet will contain less than 1000 entries. Due to the fact that any workaround would have to encrypt at least 1 entry (~ 8ms) this workaround would save around 15ms - 8ms = 7ms. This is clearly insignificant. Big overhead for syncing the wallet seems to be a myth.