Jump to content

Joseph MItzen

Members
  • Content Count

    270
  • Joined

  • Last visited

  • Days Won

    7

Everything posted by Joseph MItzen

  1. Joseph MItzen

    Quality Portal going to be moved

    If the only motivation was saving some money they could use an open source alternative, such as https://www.openproject.org/blog/open-source-jira-alternative/ or the brand new https://plane.so/
  2. About a month ago I was doing some benchmarks of FreePascal under Linux and got an unexpected result. Thanks to some help here I was able to get Delphi Community Edition installed yesterday and found the same anomaly with Delphi targeting Windows. I was wondering if I'm missing something in the below benchmark or something has changed with the new compiler and there's something I'm doing I'm not aware of that significantly impacts performance. The benchmark consists of summing the total of all the numbers between 1 and 1 billion which are evenly divisible by 3 or 5 and printing the total. It seems to me that it's a short, simple and straightforward test that should have one simple, obvious way to implement it in Pascal: program numtest8; Var total, num : Int64; begin total := 0; for num := 1 to 1000000000 Do if (num mod 3 = 0) or (num mod 5 = 0) Then total := total + num; WriteLn(total); end. Compiled with maximum performance under FreePascal (I tried other O settings; they didn't make any difference) these are the results I get on a Ryzen 2700 8 core CPU with stock cooler, best of 3: 64bit, Linux: 11.36 seconds, 99% CPU 64bit, Windows 11 VM, 11.43 seconds (PowerShell doesn't report CPU usage with the timing information) This is the figure for Delphi: 64bit, Windows 11 VM: 11.38 seconds Those figures seem rather consistent across two compilers, two operating systems, a VM and bare metal, so nothing weird. But here's the weird part (cue spooky music): I was also performing the benchmark across other languages, single core vs. parallel, etc. One language tested was Python. I was able to create a single-threaded Python version that beat a multicore version, but that's a weird result for another forum. It's this that has me stumped. What follows is a test with PyPy, a JIT-enabled version of the Python runtime. Here's the source code: total = 0 for x in range(1, 1_000_000_001): if x % 3 == 0 or x % 5 == 0: total = total + x print(total) Note: if I were performing the benchmark this way in regular Python, it'd still be running; loops kill Python performance. The best way of writing this code in regular Python gives a result of 1 minute, 15 seconds (!!!). But PyPy was much better... too much better: PyPy3.9 v7.3.8, 64bit, Linux: 3.34 seconds, 99% CPU PyPy3.9 V7.3.8 64bit, Windows VM: 3.41 seconds PyPy performed over 3X faster than Delphi / FreePascal, and that's including the time it takes to compile on the fly! The CPU data from the Linux run proves what I already knew about PyPy, that it doesn't do any automatic parallelization that might explain this result. Is there some fancy new CPU instruction it could be using that the Pascal compilers aren't? I seem to recall that at least the Delphi 32bit compiler didn't perform bit-shifting to do division; could that still be the case and the divisions are killing the performance? I decided to test another JIT option for Python, Numba. Numba is intended to JIT mathematical operations only. It's not a Python runtime, but a regular library that takes Python functions and compiles them. It also has a cache function and a pre-compile option. I was lazy and since I didn't know how the pre-compile function worked I just used the cache option and ran it once to cache the compiled function then performed benchmarks. The code: from numba import jit @jit(nopython=True, cache=True, fastmath=True) def test(): total = 0 for num in range(1, 1_000_000_001): if num % 3 == 0 or num % 5 == 0: total = total + num return total answer = test() print(answer) Python3.10.2 + Numba, 64bit, Linux: 2.07 seconds, 158% CPU Python3.10.2 + Numba, 64bit, Windows VM: 2.49 seconds I can't really explain the 158% CPU figure, as I know that numba can do some parallelization but a debug run suggested it couldn't find anything to parallelize. Regardless, it knocked almost a second off the PyPy time, probably due to caching the compiled function. I could tell Numba to explicitly parallelize: from numba import jit, prange @jit(nopython=True, cache=True, parallel=True, fastmath=True) def test(): total = 0 for num in prange(1, 1_000_000_001): if num % 3 == 0 or num % 5 == 0: total = total + num return total answer = test() print(answer) And now we get: Python3.10.2 + Numba, 64bit, Linux: 0.84 seconds, 743% CPU Python3.10.2 + Numba, 64bit, Windows VM: 1.20 seconds Clearly here the CPU results under Linux are consistent with an 8-core CPU. So the mystery is: With a statically typed, compiled language, we get circa 11.4 seconds across OSes and compilers. With a dynamically typed language with its own runtime VM, and one notoriously slow at that, we get 3.4 seconds at worst including JIT compile time, , 2.0 - 2.5 seconds pre-compiled with some possible automatic optimization, and 0.8 - 1.2 seconds with explicitly requesting the loop be parallelized. Those results are... unexpected. Now I honestly thought that JITted Python could match or ever-so-slightly beat FreePascal, because I've seen that happen before several years ago. But at least 3X faster to 10X faster? That was a shock. I'm half hoping someone will tell me I'm an idiot and I should never write Pascal code like that and if I just do X it'll speed up 300%. If not, my best guess after days of thought is that vague memory about bit-shifting. I remember when I read that Delphi didn't do that because Tiny C, a C compiler so tiny it fits on a 3.5" floppy disk - with operating system! - only has three optimizations, but one of them is bit-shifting. That would seem to imply it's rather useful. I'd be interested if anyone has any insight into why Delphi and FreePascal performed so poorly in this benchmark. I'd really like to rule out any mistakes on my end. If we can figure out what's killing the Delphi performance - and it's not me - these results should make for a very, very interesting QC feature request.
  3. I would think delivering software and information to customers would be mission-critical infrastructure. Honestly, if you're in charge of a data center, redundancy and failover are basic elements of the job, like making sure a bank account isn't overdrawn is to accounting. Netflix periodically shuts down 10% of its infrastructure to be sure their system is resistant to failure! Just like the old forum used to be made of custom code held together with wire and chewing gum and managed by a volunteer employee in their spare time, it sounds like Embarcadero has one on-premises server for all the Delphi stuff with no failover, geographically-separated redundancy, etc. Given the rock-bottom price of hardware today in addition to the ready availability of cloud virtualization, there's no excuse for not having a physical or virtual standby. On top of that, server problems aren't a sudden development like your severed cable example. Drawing upon what Uwe said, it seems reasonable to conclude they just kept ignoring recurring problems or beating it with a stick until a component failed completely, at which point they ordered a replacement.
  4. Like a lot of stuff at this company, things are probably done a certain way just because they've always been done a certain way by the same people who have worked there since the 80s or 90s.
  5. Don't worry; I figured out where they can get a replacement server!
  6. If they're not going to have any internal redundancy then they should just move to cloud servers.
  7. They did, and Larry Ellison said to try turning the servers off and back on again.
  8. Joseph MItzen

    Font selection for coding

    Well, some of us like to feel fancy when we code!
  9. Joseph MItzen

    Update issue

    He just got 11.3 running; don't frighten him further.
  10. Joseph MItzen

    String literals more then 255 chars

    Now the next step is to get escape characters like \n for a line break!
  11. Joseph MItzen

    String literals more then 255 chars

    Quite possibly. But triple quotes for multiline strings are also in Python. Python gained multiline strings with triple quotes in 2001.
  12. Joseph MItzen

    Querying mvnrepository

    Playwright and Playwright-Python (there are playright bindings for several languages) is fantastic! I believe Microsoft wrote the puppeteer library that automated Edge; the folks who wrote it left that to create playwright, which works with all the major HTML engines and incorporates some nifty features such as automatic waiting for elements. It's well-documented, too. Lots of nice features, including being able to save and load context (to preserve things such as login cookies). Some sample code from a program I wrote that needed to automate some actions with the Internet Archive: Logging in and saving context so I never have to do it again: browser = playwright.firefox.launch() context = browser.new_context() page = context.new_page() page.goto("https://archive.org/") page.get_by_role("link", name="Log in").click() page.get_by_label("Email address").fill("jgm@myself.com") page.get_by_label("Password").fill("**********") page.get_by_role("button", name="Log in").click() context.storage_state(path=STATE_FILE) There's an expect function with optional timeout that can be used to wait for things: page.goto(url) borrow_button = page.get_by_role("button", name="Borrow for 1 hour") expect(borrow_button).to_be_visible(timeout=60000) borrow_button.click() return_button = page.get_by_role("button", name="Return now") expect(return_button).to_be_visible(timeout=60000) And I forgot one of the coolest things - it can run visible or headless. There's a mode you can start it in so that the browser is visible, along with another editing window. Then you can just click and type in the browser window, and the code it would take to replicate those actions appears in the editing window! This is a super-quick way to start a project - no need to start searching through the HTML looking for object names, etc. Just start interacting with the website and all the appropriate code is determined and generated for you. Copy and paste that into your project source code and then tweak as appropriate and you're good to go. There are lots of other nice features including being able to emulate mobile browsers,.
  13. Joseph MItzen

    Current subscription required to download ?

    I've been doing some checking and Microsoft is working on their own package manager, WinGet. It would be nice if Embarcadero supported WinGet or chocolately in the future to assist in automated deploys on PCs or VMs. That's the simplest solution to alleviate users' complaints and remove any support burden Embarcadero feels around hosting install files.
  14. Joseph MItzen

    Current subscription required to download ?

    I hope not, because there's a Smoothless In Delphi Seattle joke in there somewhere.
  15. Joseph MItzen

    Current subscription required to download ?

    Is it really "just", or are they going to try to talk the caller into upgrading/renewing first? Has anyone ever tried it and reported what their experience was? I would imagine the whole point of routing the call through sales would be to try to treat the call as a sales lead rather than a support request. If not, this change doesn't make sense.
  16. Joseph MItzen

    Current subscription required to download ?

    I've not encountered this limited download period with software in recent times. If I buy a game from Steam, I can download it as many times as I want - even the new Baldur's Gate 3, which I hear is over 100GB! If I buy a game from Epic, I can download it again whenever I want - even if Epic no longer sells the game. The same applies to games I buy from GOG. If I buy an e-book from Amazon, I can re-download it whenever I want. Microsoft makes copies of Visual Studio and related tools available from 2013 onward. I can download a copy of the latest Windows ISO whenever I want, even from a non-Windows PC. I can re-download software from JetBrains whenever I want - in fact, they have a tool called Toolbox that handles (re)installation, and you can even download and install all the Jetbrains software you have purchased in one click! They also store your software settings in their cloud with five settings slots so you can even have the desired settings downloaded (say, one slot for PC, one for laptop, etc.). It's the old "like a book" rules too, so there's no installation counter. So I'd say across all different types of software, including development tools, as well as digital media it's not common to not be able to readily re-download something you've already purchased.
  17. Joseph MItzen

    Current subscription required to download ?

    That's an inappropriate comparison; digital and physical media are different in every way which matters for this comparison. Digital media doesn't cost money to produce extra copies; digital media doesn't take up warehouse space. How much software do you buy that has a maintenance subscription, or is this just a Delphi ecosystem thing? I've not encountered commercial development software that would refuse to let you re-download software you've already paid for. Why would you put up with that kind of treatment? You have to maintain a hard drive full of software setup packages; I can take a minimal net install ISO (220MB) and in short order (re)install a full OS and all software required, development and otherwise so long as an Internet connection is available. Heck, if ipxe support is available I don't even need the initial install medium! You might want to reevaluate your software tool chain.
  18. Joseph MItzen

    Handling Python indented blocks with ExecString()

    This would make Python users recoil in horror, but there are ways to turn Python code into single lines! https://jagt.github.io/python-single-line-convert/ I don't know anything about Python4Delphi, but see if exec("""\npi = 3.1415926\nprint(pi)\nif pi > 0.0:\n print('pi is positive')\nelse:\n print('pi is negative')\n""") runs. Maybe it could run without the exec if you turned the \n instances into #13s. I don't know what your app is, but being able to use Octave scripts in it is pretty cool.
  19. Joseph MItzen

    Problems with Delphi class structure / visibility

    Python is more object-oriented than Delphi (EVERYTHING is an object - types, functions, classes, even numbers) and there is no enforced "private" setting. Privacy is only by naming convention as a guideline. And you don't even need to save its code to a cassette tape! 🙂 There's basically two schools of thought in programming language design - that you have to hide and control everything to "protect" users or developers or the system, and the other school is about giving power to the developers to do whatever they wish and put responsibility for doing it properly and safely on the developer, not the language/compiler. I believe Guido Van Rossum, the creator of Python, dubbed the latter design view the "we're all adults here" philosophy. Which view has more merit is up to designers and developers to decide for themselves, but it's clearly possible to design object-oriented features into languages using either approach. And on a marginally-related note, the Internet Archive had a great write-up recently about programs stored on cassette tape... 🙂 https://blog.archive.org/2023/05/02/the-easy-roll-and-slow-burn-of-cassette-based-software/
  20. Joseph MItzen

    C to Pascal

    My buddy Bing loves Delphi. When we have discussed it it defends its virtues quite strongly.
  21. Joseph MItzen

    String literals more then 255 chars

    Really? You've never needed a JSON literal, or an HTML literal, or an XML literal, or some template string literal? Heck, what about SQL queries? SELECT DATE_FORMAT(co.order_date, '%Y-%m') AS order_month, DATE_FORMAT(co.order_date, '%Y-%m-%d') AS order_day, COUNT(DISTINCT co.order_id) AS num_orders, COUNT(ol.book_id) AS num_books, SUM(ol.price) AS total_price, SUM(COUNT(ol.book_id)) OVER ( ORDER BY DATE_FORMAT(co.order_date, '%Y-%m-%d') ) AS running_total_num_books FROM cust_order co INNER JOIN order_line ol ON co.order_id = ol.order_id GROUP BY DATE_FORMAT(co.order_date, '%Y-%m'), DATE_FORMAT(co.order_date, '%Y-%m-%d') ORDER BY co.order_date ASC; This limitation has nothing to do with being readable. It has to do with ancient Turbo Pascal code still in the IDE (ultimate source: Allan Bauer via Mason Wheeler). C++, Java, Python, Swift, Javascript, Ruby, Rust (to name a few) all have long/multi-line string support in one form or another. Clearly it's useful.
  22. Joseph MItzen

    String literals more then 255 chars

    This is it. What I believe I heard when I complained about this in 2012 (!!!) from Mason Wheeler who got it from Allan Bauer was that it was due to legacy Turbo Pascal code in the IDE that they don't plan on touching. Splitting strings yourself is just ridiculous. It's 2023 and we've got Star Trek computer-grade AI with ChatGPT and BingBot and humanoid robots coming shortly. Way past time to join... well, the 20th century. Forget long strings... this needs to be fixed for multi-line strings to be feasible. This limitation drove me nuts in 2012 when I was trying to help someone parse some nasty HTML and I tried to enter the text into Delphi and realized the limitation was still there. Fine, I'll do it in Lazarus/FreePascal... guess what? They're limited to 255 characters too, which is bizarre. It's like they artificially limited themselves to match Delphi's limitations! It's long past time that one should be able to write HTML := "<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>My test page</title> </head> <body> <img src="images/firefox-icon.png" alt="My test image" /> </body> </html>"
  23. Joseph MItzen

    String literals more then 255 chars

    I first complained about that limitation in November of 2012. 😞 I think I heard it was due to legacy Borland Turbo Pascal code. 😞 The ridiculous thing is that FreePascal's Lazarus IDE has the same limitation, like they were striving for bug-for-bug compatibility or something.
  24. Joseph MItzen

    TSuperObjectIter ObjectFindFirst problem

    I know how to write a function that does this IF one can tell what the type is of a parsed element. But from the minimal "documentation" I see that the user can typecast an element but I don't see a way to check if something is an object or array. If there's no ability to do that, then I'm not sure if one can do this type of search with SuperObject... well, maybe with some ugly exception-handling.... I'll have to test this out later today.
  25. Joseph MItzen

    TSuperObjectIter ObjectFindFirst problem

    To be fair, that's precious little documentation. It's more like a few examples. I haven't used this library before and when checking I found that even the source code wasn't documented at all. 😞
×