Hacker Newsnew | past | comments | ask | show | jobs | submit | srcreigh's commentslogin

ChatGPT also loves Aho-Corasick and seems to overuse it as an optimization fall back idea. ChatGPT has suggested the algorithm to me but the code ended up slowing down a lot.

ChatGPT was heavily RL'd on competitive programming in 2025, and aho-corasick is a traditional algorithm in the competitive programming space.

It's 2 or more spaces, not four


today i learned


Re "is fast as can be": in my experience generating C/Zig code via Codex, agent generated code is usually several multiples slower than hand optimized code.


Yeah, I’m sure my Claude generated email client could be even faster if I wrote it by hand. Modern computers can retire billions of instructions per second per core. All operations that aren’t downloading or processing gigabytes of data should be instant on modern computers.

Claude’s toy email client gets closer to the speed limit than Gmail does. Why is Gmail so slow? I have no idea.


I find the sweet spot is to take LLM generated code, then profile manually and heavily supervise or hand implement specific improvements.


You can also let the agent use a profiling tool. It probably cannot beat you, but does find and improve a lot of things for sure.


Look, it's an RSS reader, not a numeric solver for PDEs. What I clearly meant was: Every interaction is instant, no noticable delay at all, except the reader view, which makes a network request to an external site.


Hey, sorry, I just have to defuse assumptions people make when they see Rust, LLMs, and "as fast as can be" in short proximity. Your project is obviously cool, and I don't think the fact that it's likely still multiples more resource intensive than an absolutely minimal version takes away from that.


you have to ask it to profile and optimize the code for you. Then have it document the changes and run it in a loop. It’ll do wonders.

I asked a cursor agent to do the same for a geotiff to pmtiles converter. It managed to optimize the performance from tens of days to half a day for the case I wanted to solve.


Given parent and GP are both using Claude... have you tried Claude? (I say this as someone who has not tried Claude recently. I did try Claude Code when it first came out, though.)


First, it is important for these discussions that people include details like I did. We're all better off to not generalize.

RE: Claude Code, no I haven't used it, but I did do the Anthropic interview problem, beating all of Anthropic's reported Claude scores even with custom harnesses etc.

It's not a dunk that agents can't produce "as fast as can be" code; their code is usually still reasonably fast; it's just often 2-10x slower than can be.


There is a lot to be done with good prompting.

Early on, these code agents wouldn't do basic good hygiene things, like check if the code compiled, avoid hallucinating weird modules, writing unit tests. And people would say they sucked ....

But if you just asked them to do those things: "After you write a file lint it and fix issues. After you finish this feature, write unit tests and fix all issues, etc ..."

Well, then they did that, it was great! Later the default prompts of these systems included enough verbiage to do that, you could get lazy again. Plus the models are are being optimized to know to do some of these things, and also avoid some bad code patterns from the start.

But the same applies to performance today. If you ask it to optimize for performance, to use a profiler, to analyze the algorithms and systemically try various optimization approaches ... it will do so, often to very good results.


Yep. Claude code is best thought of as an overachieving junior / mid. It can run off and do all sorts of work on its own, but it doesn't have great instincts and it can't read your mind about what you want.

Use it as if you're the tech lead managing a fresh hire. Tell it clearly what you want it to focus on and you get a much better result.


That's a given, and agents still come out 2-10x slower in my experience.


Thanks Andy.

Would you endorse the pattern I described in my article if the calling code could have other uses for the diagnostic info than just logging?

In my project I decided that the CLI main should be the place with a reporting mechanism. All the internal code is agnostic to how errors are handled. Many errors could be retried, even if they are currently not, and in some cases you also need extra diagnostic data in order to retry. For example if 1/4 plugins fails to load, I would need to know which one failed to ask the user interactively where to find it or whether to skip it before retrying. There's a few different errors like this, and layers between the handling code and the error source code, which is how I ended up with the union(enum) diagnostic keyed by error code pattern.

It seems that "error codes aren't a reporting mechanism", practically speaking, means that internal application code should just log its own error and return a generic error code that bubbles up unhandled out of main. You decided that this wasn't ok for allocation failures and encourage retrying those, which I find to be inspiring, but apparently most types of application errors are fine to essentially log and ignore. So that is confusing.

I love Zig, and look up to you a lot, so thanks for all your efforts over the years!


This is just a "complex real world app code" extension of the stdlib Diagnostics pattern.

  % rg Diagnostics zig/lib/std | wc -l
  165
The zig stdlib kind of has it easy because, for example, the json module can have one schema for error diagnostics. An app that stitches together a bunch of libraries and has a few internal modules is going to want some different Diagnostics schemas for different errors, and sharing those schemas and bubbling them up, so that's just what this is.


Note the person behind your link isn't Andrew Kelley


Oh thanks a bunch. That’s confusing. Removed that.


What more do you want than what's covered in the post?

To me, this post is proof zig doesn't need "proper support". You can already have extremely ergonomic error payloads with existing language features.

Earlier version of this post had some language feature ideas, but then I realized Zig already had all the capabilities, so I just removed that section.

For example, I used to think it'd be nice for functions to be a namespace, so I didn't have `myFunc` and `MyFuncDiagnostics`. But then I realized that the Diagnostics type doesn't need its own name; you can just put the type in the function signature, and use a function like `diagnostics.OfFunction(fn)` to extract the type from the function definition, so you can just write this:

  var diag: diagnostics.OfFunction(myFunc) = .{};
  const res = myFunc(foo, bar, &diag) catch |err| ...;
As another example, I used to write out the `error{OutOfMemory, ...}` type explicitly in addition to the tagged union payload, but then realized you can generate an error set from the union tags at comptime.

Do you want automatic inference of the error payload type? So zig creates a special tagged union error payloads type for you automatically? It seems complicated and maybe not a good idea. Do you really want your function to return an invisible 20 elements union on error? Do you want to call a someone else's function which returns an invisible 20 elements union on error? You know, maybe it's not a good idea.


More than anything I want "Here's the current officially sanctioned best practice of how to report errors with payloads". For a language that's highly opinionated about everything it's strangely unopinionated here and worse off for it because many libraries just swallow useful diagnostic information, some of my own projects included.

There's a barrier to setting up the diagnostic pattern. When you're in the greenfield phase it's easy to search for information about error reporting, discover various different approaches and long threads of people arguing about what better and just say "ah screw it, I have more important things to do right now" and postpone the decision.

Your approach is fine, I don't love how verbose it is but it could probably be tweaked. If this is the way forward then it should be included in stdlib, documented, and promoted as the recommended way of reporting errors.


I agree. You understand why I wrote this post. It's what I wanted to read 3 weeks ago. We're told "Use Diagnostics like the json stdlib module!" but then you realize the json module is way too simplistic for a complicated application.

But also, I'm sure this method has flaws and can be greatly improved, so hopefully we can come to the right solution.


> You can already have extremely ergonomic error payloads with existing language features.

I think you meant extremely unergonomic. If you take a dev poll, 8/10 developers would not find the solution ergonomic at all.


Are you sure? Just because you feel that way doesn't mean you can just make up a statistic that supports your viewpoint.

In my experience, ergonomics in Zig means something other than ergonomics in many other languages. In plenty of languages, ergonomic code is basically just writing as few characters as possible and being able to achieve complex logic with little boilerplate. In Zig, it feels good to be able to compose the conceptually simple language features into an optimal solution to your problem, even if it results in code that is maybe not aesthetically pleasing on first glance.

I'm not going to declare that this solution is ergonomic or not, you can't always tell just by looking at Zig code whether using it is ergonomic, but by that same logic we shouldn't dismiss it off hand.


> In my experience, ergonomics in Zig means something other than ergonomics in many other languages.

So an opinion...


Obviously


It's just stored as a [256]u8 in the struct.

  // sqlite.zig
  pub const ErrorPayload = struct {
      message: [256]u8,
  
      pub fn init(db: *c.sqlite3) @This() {
          var self = std.mem.zeroes(@This());
          var fw = std.Io.Writer.fixed(self.message[0..]);
          _ = fw.writeAll(std.mem.span(c.sqlite3_errmsg(db))) catch |err| switch (err) {
              error.WriteFailed => return self, // full
          };
          return self;
      }
  };


And what pattern would you recommend if you needed to allocate?


It's worth every effort to avoid situations where a function creates extra clean up responsibilities to the caller only on error conditions.

If I really needed a large error payload, too big to fit on the stack, I'd probably want to do something like this:

  const errbuf = try alloc.alloc(u8, 1024*1024*1024);
  module.setErrorBuf(&errbuf)
  defer {
    module.setErrorBuf(null);
    alloc.free(errbuf);
  }

  var func_diag = diagnostics.OfFunction(module.func){};
  module.func(foo, bar, &func_diag) catch |err| switch (err) {
    error.BigPayload => {
      const payload = func_diag.get(error.BigPayload);

      // The payload can reference the 1MiB of data safely here,
      // and it's cleaned up automatically.
    }
  }


The diagnostic struct could contain a caller-provided allocator field which the callee can use, and a deinit() function on the diagnostic struct which frees everything.


Care to elaborate?


As an American, I can freely oppose the current regime. I routinely say, both online and in real life under my government name, that Donald Trump and his cronies are criminals, that everyone should work hard to stop them from achieving their goals and ideally they should all get life sentences once we throw them out of office. I’ll never face legal or even professional consequences for saying this, and even within the most authoritarian regime in generations few officials argue that I should.

Unless I’ve been severely misinformed, someone saying similar things about Xi Jinping on a Chinese tech forum would be swiftly banned and likely arrested.


The US regime allows its citizens to criticize politicians. That doesn't mean you are free to criticize those in power.


Yes, actually, it means just that.


these days the us government (well trump) will let you speak when your speak is inconsequential but will repress when you have a little bit of reach (universities, research, tv shows etc.). and he is modifying the system in order to reinforce his ability to do so (putting his people everywhere he should not).

but yes, you can criticize as much as you want as long as nobody is listening to you (for now).

in europe we are getting close to parity with china in this aspect though.


Buddy what article do you think you are currently commenting on?


I'm commenting on an article about an American advocacy group filing a lawsuit accusing high-ranking government officials of misconduct, another thing that similarly situated people in China cannot do. Again, happy to admit the possibility I could be wrong: are there cases I don't know about where Chinese citizens file lawsuits accusing the Ministry of State Security of misconduct?

The content of the lawsuit argues, correctly in my view, that American speech protections are so strong they go beyond mere criticism. American citizens have a right to publish detailed information about the location of government agents, even if this information makes law enforcement harder and even if the agents fear being tracked might be dangerous for them.


Thank you. Your reply is more respectful than I earned.

On paper americans have all these rights, but surely you are seeing how the paper is not matching the reality in many ways, and very little is being done to fix that as tens of millions of americans outright support the paper being ignored, so how can you trust that disparity to not come for your paper rights to speak? Already those same courts you are relying on have thrown away real rights, and the administration itself flouts those same courts regularly.

Chinese citizens have a lot of rights on paper too, including right to freedom of expression. I would bet you could find occasional cases or situations in China where some lowly citizen "wins" against the government, as that always looks good, but that doesn't make it meaningful and I can't read or speak any Chinese languages to back up this suspicion.

It's only going to take one Supreme Court case to change the paper rights. Do you feel this supreme court has shown a preference for principles over administration?


I mostly don't agree that the paper isn't matching the reality. The Trump regime does a lot of terrible things, and works hard to create the impression that this means they're omnipotent and can do whatever terrible things they want to anyone who steps out of line, and I think it's entirely correct to be stressed and worried that one day they might be able to put that into practice. But today it's not so. A guy yelled to Trump's face that he's a pedophile protector last month (https://www.cbsnews.com/detroit/news/ford-worker-keeping-job...), and Trump could not do anything in response other than impotently flip him off.


Trump complained to Ford about it and they immediately suspended him without pay.

What protected him wasn't being in America - it's that he had a strong union. Which most Americans don't have.


There's a relevant open issue[1] here about stack memory optimization. It would be nice to be able to use a [500]u8 in a block and another [500]u8 in another block, and have that only contribute 500 bytes to the stack frame, but Zig can't currently do this.

(The green threads coro stack stuff makes this more important.)

[1]: https://github.com/ziglang/zig/issues/23475#issuecomment-279...


Please stop posting 0-information-content complaints.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: