ENH: reduce allocations/overhead when reading PtrList

- replace SLList with direct handling (like a hand-rolled DynamicList)

ENH: support PtrList transfer for polyMesh::addZones
This commit is contained in:
Mark Olesen
2022-09-23 20:19:20 +02:00
parent cbace69896
commit 4710528448
6 changed files with 68 additions and 61 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,7 +27,6 @@ License
\*---------------------------------------------------------------------------*/
#include "PtrList.H"
#include "SLList.H"
#include "Istream.H"
#include "INew.H"
@ -97,11 +96,10 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
}
else if (tok.isPunctuation(token::BEGIN_LIST))
{
// "(...)" : read as SLList and transfer contents
// This would be more efficient (fewer allocations, lower overhead)
// using a DynamicList, but then we have circular dependencies
// "(...)" : read like a DynamicList
SLList<T*> slList;
// The length read
label len = 0;
is >> tok;
while (!tok.isPunctuation(token::END_LIST))
@ -115,18 +113,25 @@ void Foam::PtrList<T>::readIstream(Istream& is, const INew& inew)
<< exit(FatalIOError);
}
slList.append(inew(is).ptr());
if (!len)
{
// Initial reserved size (avoid unnecessary doubling)
resize(64);
}
else if (len == this->size())
{
resize(2*len);
}
T* p = inew(is).ptr();
set(len, p);
++len;
is >> tok;
}
resize(slList.size());
// A list of pointers - can simply shallow copy them
label i = 0;
for (T* ptr : slList)
{
set(i++, ptr);
}
// Set list length to that read
resize(len);
}
else
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -90,13 +90,7 @@ void Foam::Detail::PtrListDetail<T>::free()
for (label i=0; i<len; ++i)
{
T* ptr = ptrs[i];
if (ptr)
{
delete ptr;
}
delete ptrs[i];
ptrs[i] = nullptr;
}
}

View File

@ -31,8 +31,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef INew_H
#define INew_H
#ifndef Foam_INew_H
#define Foam_INew_H
#include "autoPtr.H"
@ -41,7 +41,8 @@ Description
namespace Foam
{
// Forward declarations
// Forward Declarations
class dictionary;
class Istream;
/*---------------------------------------------------------------------------*\
@ -53,9 +54,8 @@ class INew
{
public:
//- Construct null
INew()
{}
//- Default construct
INew() = default;
//- New from Istream
autoPtr<T> operator()(Istream& is) const

View File

@ -1011,57 +1011,39 @@ void Foam::polyMesh::addPatches
void Foam::polyMesh::addZones
(
const List<pointZone*>& pz,
const List<faceZone*>& fz,
const List<cellZone*>& cz
PtrList<pointZone>&& pz,
PtrList<faceZone>&& fz,
PtrList<cellZone>&& cz
)
{
if (pointZones().size() || faceZones().size() || cellZones().size())
if (pointZones_.size() || faceZones_.size() || cellZones_.size())
{
FatalErrorInFunction
<< "point, face or cell zone already exists"
<< abort(FatalError);
}
// Point zones
// Point zones - take ownership of the pointers
if (pz.size())
{
pointZones_.setSize(pz.size());
// Copy the zone pointers
forAll(pz, pI)
{
pointZones_.set(pI, pz[pI]);
}
pointZones_.clear();
pointZones_.transfer(pz);
pointZones_.writeOpt(IOobject::AUTO_WRITE);
}
// Face zones
// Face zones - take ownership of the pointers
if (fz.size())
{
faceZones_.setSize(fz.size());
// Copy the zone pointers
forAll(fz, fI)
{
faceZones_.set(fI, fz[fI]);
}
faceZones_.clear();
faceZones_.transfer(fz);
faceZones_.writeOpt(IOobject::AUTO_WRITE);
}
// Cell zones
// Cell zones - take ownership of the pointers
if (cz.size())
{
cellZones_.setSize(cz.size());
// Copy the zone pointers
forAll(cz, cI)
{
cellZones_.set(cI, cz[cI]);
}
cellZones_.clear();
cellZones_.transfer(cz);
cellZones_.writeOpt(IOobject::AUTO_WRITE);
}
}
@ -1080,6 +1062,23 @@ void Foam::polyMesh::addPatches
}
void Foam::polyMesh::addZones
(
const List<pointZone*>& pz,
const List<faceZone*>& fz,
const List<cellZone*>& cz
)
{
// Acquire ownership of the pointers
addZones
(
PtrList<pointZone>(const_cast<List<pointZone*>&>(pz)),
PtrList<faceZone>(const_cast<List<faceZone*>&>(fz)),
PtrList<cellZone>(const_cast<List<cellZone*>&>(cz))
);
}
const Foam::pointField& Foam::polyMesh::points() const
{
if (clearedPrimitives_)

View File

@ -606,6 +606,14 @@ public:
const bool validBoundary = true
);
//- Add mesh zones
void addZones
(
PtrList<pointZone>&& pz,
PtrList<faceZone>&& fz,
PtrList<cellZone>&& cz
);
//- Add mesh zones
void addZones
(

View File

@ -271,7 +271,8 @@ public:
//- Clear the zones
void clear();
bool hasFaceAreas() const { return bool(zoneMapPtr_); }
//- The zoneMap has been allocated
bool hasZoneMap() const noexcept { return bool(zoneMapPtr_); }
// Member Operators