Git Product home page Git Product logo

Comments (15)

gregmarr avatar gregmarr commented on June 9, 2024

Even without using this library, I would not expect to be able to have a function that recurses 100,000 times, unless I have a massively huge stack. If you optimize this, you might get away with it due to tail call optimization converting it from recursive to iterative.

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

If I remove the json argument, then it works as expected --- I can finish the entire execution. In fact, as long as I don't use json in the function, then it works. This means that something is happening when json is being used that causes this (this happens even if I'm just extracting a value from the json, like std::string a=name["glossary"]["title"];.

from json.

nlohmann avatar nlohmann commented on June 9, 2024

You pass by value - this means you create thousands of copies of the json value. Can you try to pass by reference?

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

I already tried that --- same problem, just happens later.

from json.

nlohmann avatar nlohmann commented on June 9, 2024

I see the same behavior with

#include <string>

void print_json(std::string name,int n){
	if (n<=0){
		return;
	}
	printf("%s\n",name.c_str());
	print_json(name, n-1);
}

int main(int argc, char** argv){
	std::string testing = R"({"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}})";
	print_json(testing,100000);

	return 0;
}

As @gregmarr mentioned, you are testing against the stack limits, not against the library.

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

That's weird --- If I do that (and use references), the program completes just fine, it's just that references with json is not enough to complete the program.

from json.

gregmarr avatar gregmarr commented on June 9, 2024

By adding a local variable with a destructor, you are defeating the tail call optimization.

void print_json(std::string const &name,int n){
	if (n<=0){
		return;
	}
	std::string copy = name; // If you comment this out, it will succeed
	print_json(name,n-1);
}

int main(int argc, char** argv){
	std::string testing = R"({"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}})";
	print_json(testing,100000);

	return 0;
}

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

I understand that, but replacing json reference with a std::string reference causes the program to terminate (in both cases, there are no local variables).

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

However, using -O3 causes this reproducer to succeed. Unfortunately, my actual function is not tail recursive, so the compiler can't optimize for it.

from json.

gregmarr avatar gregmarr commented on June 9, 2024

The local variable is here, it's a temporary, but it does appear to be affecting the optimization:

printf("%s\n",name.dump(-1).c_str());
              ^^^^^^^^^^^^^

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

Ah, that's why std::string::c_str works --- it's a pointer, which doesn't need to be deallocated.

Since my function is not tail-recursive, it doesn't seem to apply. However, in my function, I'm not dealing with 10000 iterations, but at most 15, so there's something else going on (I also get a bus error). Given that references alleviate some of the problem tells me that something probably went awry. But I don't think this is due to the library at this point, so I'll close this issue.

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

A problem though: when I debug applications, I need to get the json string so I can externally parse it --- however, as you can see, if I'm in heavily nested frame, and I try to dump() a large json object, I get a stack overflow. Is there a way to get the raw char* directly, to avoid making a local variable?

from json.

gregmarr avatar gregmarr commented on June 9, 2024

There is no string form of a large object until you generate it using dump(), and that form is not stored, only returned to you.

from json.

DUOLabs333 avatar DUOLabs333 commented on June 9, 2024

When I call test["a"]["b"]["c"] on a json& test, are new objects created/copied for each of the keys? If so, that could explain the overflow.

from json.

gregmarr avatar gregmarr commented on June 9, 2024

test["a"] returns a reference, which you then access by calling ["b"], which returns a reference, which you then access by calling ["c"], which returns a reference. This reference is either const or non-const depending on the const-ness of test. If test is non-const, then it can create new sub-objects, but that's all heap-based. The references may or may not be stack objects, or may just be stored in registers, depending on the optimization, but if they are stack objects, then they are pointer/reference sized.

from json.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.